Суммируйте значения в столбце на основе строк из нескольких столбцов в pandas / python - PullRequest
0 голосов
/ 04 мая 2018

У меня есть датафрейм с 4 столбцами. 3 из этих столбцов содержат строковые значения (имена людей), а 4-й столбец имеет значение int (оклад за выполненную работу).

Строковые значения также не являются уникальными, одна и та же строка будет отображаться несколько раз в каждом столбце, но не более одного раза в строке.

data = {
    'worker1': ['Sam', 'Jack', 'Matt', 'Paul', 'Tim'],
    'worker2': ['Alex', 'Amy', 'Sam', 'Alice', 'Amanda'], 
    'worker3': ['Alice', 'Aaron', 'Tony', 'Jack', 'Sam'],
    'earnings': [4564552, 4573547, 3567567, 6357653, 7648576]}

df = pd.DataFrame(data, columns = ['worker1', 'worker2', 'worker3', 'earnings'])

print(df)

worker1    worker2    worker3    earnings
'Sam'      'Alex'     'Alice'    4564552
'Jack'     'Amy'      'Aaron'    4573547
'Matt'     'Sam'      'Tony'     3567567
'Paul'     'Alice'    'Jack'     6357653
'Tim'      'Amanda'   'Sam'      7648576

Итак, мне нужно сложить все доходы, связанные с конкретным именем, независимо от того, отображается ли оно в столбцах 1, 2 или 3. Я не уверен, стоит ли мне использовать для этого функцию groupby, создать словарь или перейти другой маршрут.

Это то, чего я пытаюсь достичь:

workers    total_earnings
Sam        16080695
Alex       4564552
Alice      10922205
Jack       10931200
Amy        4573547
Aaron      4573547
Matt       3567567
Tony       3567567
Paul       6357653
Tim        7648576
Amanda     7648576

Я довольно новичок в пандах, поэтому я в месте, где я не знаю, какие функции я могу использовать для чего-то подобного. В основном я пытался использовать функцию groupby, но это было катастрофой.

Любая помощь будет принята с благодарностью.

Ответы [ 4 ]

0 голосов
/ 06 мая 2018

Мне очень нравится ваш подход. Есть несколько строк, без которых вы можете обойтись хотя бы для фрейма данных, определенного в вашем вопросе выше. Интересно, что если вы используете groupby так, как это указано в моем другом ответе, вы получите кадр данных, а не ряд, а затем вы можете связать метод reset_index с той же строкой.

df1 = pd.melt(df, id_vars = ['earnings'], value_name = 'workers', value_vars = ['worker1', 'worker2', 'worker3'])   
df1 = df1.drop('variable', axis=1).groupby('workers').sum().reset_index()
0 голосов
/ 05 мая 2018

Немного долго, но делает то, что вы хотите:

>>> df1 = pd.concat([df.groupby('worker1').sum(), df.groupby('worker2').sum(), df.groupby('worker3').sum()])
>>> df1.groupby(df1.index).sum()
        earnings
Aaron    4573547
Alex     4564552
Alice   10922205
Amanda   7648576
Amy      4573547
Jack    10931200
Matt     3567567
Paul     6357653
Sam     15780695
Tim      7648576
Tony     3567567
0 голосов
/ 06 мая 2018

Мне удалось сделать то, что я хотел, с помощью следующего кода. Это работает, но я не знаю, правильный ли это подход или самый эффективный способ сделать это. Было бы полезно получить подтверждение от кого-то с большим опытом в отношении того, является ли это правильным способом решения этой проблемы. Спасибо за всю помощь, которую вы оказали в этом!

df1 = df[['worker1', 'worker2', 'worker3', 'earnings']].copy()
df1.dropna(subset=['earnings'], inplace=True)
df1.reset_index(drop=True, inplace=True)

df1 = pd.melt(df1, id_vars = ['earnings'], value_name = 'workers', value_vars = ['worker1', 'worker2', 'worker3'])   

df1.drop('variable', axis=1, inplace=True)    
df1 = df1.groupby('workers')['earnings'].agg(np.sum)
df1 = pd.DataFrame({'workers':df1.index, 'Earnings':df1.values}) 
0 голосов
/ 05 мая 2018

Сложность здесь заключается в том, как был построен фрейм данных. Все имена работников должны быть в одном столбце, а их соответствующие доходы - во втором столбце. Есть термин «аккуратные данные», который стоит узнать о https://en.wikipedia.org/wiki/Tidy_data.

Приведенное ниже решение реорганизует фрейм данных, и, как только это будет достигнуто, общий доход для данного имени легко рассчитывается с помощью групповой обработки.

df_list = []
columns = df.columns.tolist()

for i in range(3):
    df_i = df.loc[:, [columns[i], 'earnings']]
    df_i.columns = ['worker', 'earnings']
    df_list.append(df_i)

df_1 = pd.concat(df_list)

earnings = df_1.groupby(['worker']).sum()

earnings
Out[50]: 
        earnings
worker          
Aaron    4573547
Alex     4564552
Alice   10922205
Amanda   7648576
Amy      4573547
Jack    10931200
Matt     3567567
Paul     6357653
Sam     15780695
Tim      7648576
Tony     3567567
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...