2014-10-09 1 views
1

Вопрос: С названием как условие, как достичь желаемого результата, отображаемого ниже?Поворотная рамка данных Pandas с бесщелевым daterange как индекс

Образец данных:

 Date  Client  Order 
0 1/30/1987 AAA   O.N. 111 
1 3/28/1987 BBB   O.N. 112 
2 3/28/1987 CCC   O.N. 113 
3 3/28/1987 AAA   O.N. 114 
4 3/31/1987 DDD   O.N. 115 
5 3/31/1987 BBB   O.N. 116 
6 3/31/1987 EEE   O.N. 117 
7 4/1/1987 FFF   O.N. 118 
8 4/1/1987 CCC   O.N. 119 
9 4/1/1987 AAA   O.N. 120 
10 4/2/1987 DDD   O.N. 121 

Желаемый результат:

  AAA BBB CCC DDD EEE FFF 
1987-01-30 111 NaN NaN NaN NaN NaN 
1987-01-31 NaN NaN NaN NaN NaN NaN 
1987-02-01 NaN NaN NaN NaN NaN NaN 
... 
1987-03-28 114 112 113 NaN NaN NaN 
... 
1987-03-31 NaN 116 NaN 115 117 NaN 
1987-04-01 120 NaN 119 NaN NaN 118 
1987-04-02 NaN NaN NaN 121 NaN NaN 

подходы пытались:

# Results to an error. 
df_p = df.pivot(index='Date',columns='Client',values='Order') 

# Almost there, but I don't want to iterate over each cell to get Order number. 
df_symbol = df['Client'] 
df_symbol_unique = set(df_symbol) 
index = pd.date_range(df['Date'].iat[0],df['Date'].iat[-1]) 
df_new = pd.DataFrame(np.NaN,index=index,columns=sorted(list(df_symbol_unique))) 

#    AAA BBB CCC DDD EEE FFF 
#1987-01-30  NaN NaN NaN NaN NaN NaN 
#1987-01-31  NaN NaN NaN NaN NaN NaN 
#1987-02-01  NaN NaN NaN NaN NaN NaN 
#... 

Связанные ссылки проверяются (что, кажется, не для решения проблемы):

  1. concat pandas DataFrame along timeseries indexes
  2. transpose multiple columns Pandas dataframe

Примечания:

  1. Date колонна всегда отсортированные из старейших к новейшим.
  2. Клиент никогда не будет иметь более 1 заказа/дня.
  3. Не должно быть пробелов в диапазоне дат, следовательно, index, приведенных выше.

Update:

По-видимому, действительно повторяющиеся пары клиент-заказ на более поздние сроки, в отличие от Примечание 2 выше, которое является то, что Мессинг мои данные (столько для проверки только 20000 строк в миллион, pfft) и стержень. Ответ DSM (и моя первоначальная догадка) правильна, что поворот - это решение.

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

Update 2:

Спекуляция на ответ DSM, но с использованием вместо pivot_table.

df["Date"] = pd.to_datetime(df["Date"]) 
df_p = df.pivot_table(rows="Date", cols="Client", values="Order", aggfunc=len) 
df_p = df_p.reindex(pd.date_range(df_p.index.min(), df_p.index.max())) 

дает следующий вывод на модифицированной таблице:

Client  AAA BBB CCC DDD EEE FFF 
1987-01-30 1 NaN NaN NaN NaN NaN 
1987-01-31 NaN NaN NaN NaN NaN NaN 
1987-02-01 NaN NaN NaN NaN NaN NaN 
1987-02-02 NaN NaN NaN NaN NaN NaN 
1987-02-03 NaN NaN NaN NaN NaN NaN 

[5 rows x 6 columns] 
Client  AAA BBB CCC DDD EEE FFF 
1987-03-29 NaN NaN NaN NaN NaN NaN 
1987-03-30 NaN NaN NaN NaN NaN NaN 
1987-03-31 NaN 1 NaN 1 1 NaN 
1987-04-01 2 NaN NaN NaN NaN 1 
1987-04-02 NaN NaN NaN 1 NaN NaN 

[5 rows x 6 columns] 
[Finished in 1.4s] 

достаточно хорошо для меня.

ответ

2

Нечто подобное - которая выглядит очень похоже на то, что вы пытались, если честно - работает для меня:

>>> df 
     Date Client  Order 
0 1/30/1987 AAA O.N. 111 
1 3/28/1987 BBB O.N. 112 
2 3/28/1987 CCC O.N. 113 
3 3/28/1987 AAA O.N. 114 
4 3/31/1987 DDD O.N. 115 
5 3/31/1987 BBB O.N. 116 
6 3/31/1987 EEE O.N. 117 
7 4/1/1987 FFF O.N. 118 
8 4/1/1987 CCC O.N. 119 
9 4/1/1987 AAA O.N. 120 
10 4/2/1987 DDD O.N. 121 
>>> df["Date"] = pd.to_datetime(df["Date"]) 
>>> df["Order"] = df["Order"].str.split().str[-1] 
>>> df_p = df.pivot(index="Date", columns="Client", values="Order") 
>>> df_p = df_p.reindex(pd.date_range(df_p.index.min(), df_p.index.max())) 

, который дает:

>>> df_p.head() 
Client  AAA BBB CCC DDD EEE FFF 
1987-01-30 111 NaN NaN NaN NaN NaN 
1987-01-31 NaN NaN NaN NaN NaN NaN 
1987-02-01 NaN NaN NaN NaN NaN NaN 
1987-02-02 NaN NaN NaN NaN NaN NaN 
1987-02-03 NaN NaN NaN NaN NaN NaN 
>>> df_p.tail() 
Client  AAA BBB CCC DDD EEE FFF 
1987-03-29 NaN NaN NaN NaN NaN NaN 
1987-03-30 NaN NaN NaN NaN NaN NaN 
1987-03-31 NaN 116 NaN 115 117 NaN 
1987-04-01 120 NaN 119 NaN NaN 118 
1987-04-02 NaN NaN NaN 121 NaN NaN 
+0

кажется удивительным, но я получаю 'ValueError: индекс содержит повторяющиеся записи, не может изменить форму ошибки, которая не должна быть AFAIK. Любые идеи относительно того, что может вызвать указанную ошибку? :/ – Manhattan

+0

Даже с этим 11-строчным образцом? Какую версию 'pandas' вы используете? – DSM

+0

Да, даже с этим. Кроме того, в данных я только лично проверил около 20 000 строк из миллиона, но я уверен, что нет дат с более чем одним заказом на одного клиента. Версия Pandas 0.13.1. – Manhattan

Смежные вопросы