2015-09-04 2 views
1

У меня есть dataframe, который я пытаюсь сортировать определенным образом.Сортировка данных с использованием Pandas Dataframes в Python

вход:

CompanyName count assignee_name CallType  recvd_dttm 
Company3  4   Jill   Machine1  8/28/2015 13:46 
Company3  4   Jill   Machine1  8/27/2015 13:26 
Company3  4   Jack   Machine2  8/27/2015 11:46 
Company3  4   Jill   Machine1  8/25/2015 9:56 
Company2  3   Brad   Machine1  8/29/2015 12:43 
Company2  3   Lee   Machine2  8/28/2015 13:44 
Company2  3   Lee   Machine1  8/22/2015 19:45 
Company1  2   Lee   Machine1  8/12/2015 14:47 
Company1  2   Lee   Machine2  8/11/2015 13:44 
Company0  1   Tracy   Machine2  8/31/2015 13:32 

Что я хочу:

Company3   Company2  Company1  Company0 
4    3    2    1 
Jill    Lee   Lee    Tracy 
Machine1   Machine1  Machine1  Machine2 
8/28/2015  8/29/2015  8/12/2015  8/31/2015 

Он должен вывести название компании в порядке, который проявляется в dataframe больше всего. Затем он должен показать человека, который взял вызовы MOST. Тогда информация для CallType и recvd_dttm должна быть самой последней информацией.

Я использовал это:

mode = (lambda ts: ts.value_counts(sort=True).index[0] 
        if len(ts.value_counts(sort=True)) else None) 
cols = df['CompanyName'].value_counts().index 

df = df.groupby('CompanyName')[['count','assignee_name', 'CallType', 'receiveddate']].agg(mode).T.reindex(columns=cols) 

И выводит правильно название компании и рассчитывать, но выбирает случайный вызов для другой информации, не самый последний вызов.

Я также искал в использовании нечто вроде df.groupby(['CompanyName','count']).agg(lambda x:x.value_counts().index[0])

, но я получаю сообщение об ошибке UnicodeDecodeError: 'ascii' codec can't decode byte 0xef in position 21285: ordinal not in range(128).

ответ

1
# convert datetime string to pd.timestamp 
df['recvd_dttm'] = pd.to_datetime(df['recvd_dttm'], format='%m/%d/%Y %H:%M') 

def func(g): 
    temp = g[g['recvd_dttm'] == g['recvd_dttm'].max()].iloc[0] 
    temp['assignee_name'] = g['assignee_name'].value_counts().index[0] 
    return temp.drop('CompanyName') 

df.groupby('CompanyName').apply(func).sort(['count'], ascending=False).T 

CompanyName    Company3    Company2    Company1    Company0 
count       4     3     2     1 
assignee_name     Jill     Lee     Lee    Tracy 
CallType     Machine1    Machine1    Machine1    Machine2 
recvd_dttm  2015-08-28 13:46:00 2015-08-29 12:43:00 2015-08-12 14:47:00 2015-08-31 13:32:00 
+0

Да! Это приближает меня на один шаг. Следующее - получить имя assignee_name, которое будет отображаться больше всего для этого CompanyName. Знаете ли вы, как это получить? – jenryb

+0

Как и в этом случае, для Company2 Lee появится, а не Брэд, потому что он больше подходит для звонков Company2. – jenryb

+0

@jenryb Я отредактировал сообщение, чтобы решить эту проблему. :-) –

1

Как об этом:

In [121]: most = df.groupby('CompanyName')['assignee_name'].transform(lambda x: x.value_counts().idxmax())) 

In [122]: df = df[df['assignee_name'] == most] 

In [123]: df = df.sort(['CompanyName', 'recvd_dttm']) 

In [124]: df = df.groupby('CompanyName').last() 

In [125]: df 
Out[125]: 
      count assignee_name CallType   recvd_dttm 
CompanyName             
Company0   1   Tracy Machine2 2015-08-31 13:32:00 
Company1   2   Lee Machine1 2015-08-12 14:47:00 
Company2   3   Lee Machine2 2015-08-28 13:44:00 
Company3   4   Jill Machine1 2015-08-28 13:46:00 
+0

Это замечательно, но не формат, я хотел, что очень важно для остальной части кода. Я буду рассматривать его форматирование одинаково. – jenryb