У меня есть следующий файл Excel

ID     EmpName                   date           cost
1      bob smith              01/01/2019     10
2      Jane Doe               01/04/2019     20
3      steve ray, bob smith   01/03/2017     100

Если я хочу посчитать вхождения каждого человека: Боба, Джейн и Стива ... но по идентификатору 3 (как и по другим строкам) в данных в поле имени указано несколько сотрудников, что не идеально ... что такое мой лучший подход к подсчету этого?

Ищете что-то вроде этого

employee      count       cost
bob smith     2           110
jane doe      1           20
steve ray     1           100

Второй вопрос:

Если мои данные следующие:

ID     EmpName1      Empname2    date           cost
1      bob smith                 01/01/2019     10
2      Jane Doe                  01/04/2019     20
3      steve ray     bob smith   01/03/2017     100

Может ли это быть подсчитано подобным образом?

0
Oscalation 30 Май 2019 в 05:20

2 ответа

Лучший ответ

Используя get_dummies

s=df.EmpName.str.get_dummies(', ')
pd.concat([s.sum(),s.mul(df.cost,0).sum()],axis=1)
Out[666]: 
           0    1
Jane Doe   1   20
bobs mith  2  110
steve ray  1  100

Или мы используем unnesting

df.EmpName=df.EmpName.str.split(',')
unnesting(df,['EmpName']).groupby('EmpName').cost.agg(['sum','count'])
Out[669]: 
          sum  count
EmpName             
JaneDoe    20      1
bobsmith  110      2
steveray  100      1

Обновить

s=df[['EmpName1','Empname2','cost']].melt(['cost']).groupby('value').cost.agg(['sum','count'])
s.drop('')
Out[678]: 
          sum  count
value               
JaneDoe    20      1
bobsmith  110      2
steveray  100      1

Или wide_to_long

pd.wide_to_long(df,['EmpName'],i=['ID'],j='number').groupby('EmpName').cost.agg(['sum','count'])

def unnesting(df, explode):
    idx = df.index.repeat(df[explode[0]].str.len())
    df1 = pd.concat([
        pd.DataFrame({x: np.concatenate(df[x].values)}) for x in explode], axis=1)
    df1.index = idx

    return df1.join(df.drop(explode, 1), how='left')
1
YO and BEN_W 30 Май 2019 в 02:52

Возможно, вы захотите реструктурировать ваши данные в нечто, похожее на

ID     EmpName                   date           cost
1      bob smith              01/01/2019     10
2      Jane Doe               01/04/2019     20
3      steve ray              01/03/2017     100
1      bob smith              01/03/2017     100

С этого момента вы можете использовать операторы groupby и sum, чтобы найти то, что вы ищете. Что-то вроде:

df.groupby(['EmpName'])[['cost']].sum()

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

-1
Thomas Hayes 30 Май 2019 в 02:30
56370853