我正在对小鼠进行实验。
我的df的一部分在下面。
Index Name Time Food Experiment Start
0 Peter 09:00:00 Cheese 2018-08-06 07:30:00
1 Peter 10:00:00 Nut 2018-08-06 07:30:00
2 Peter 11:00:00 Nut 2018-08-06 07:30:00
3 Peter 12:00:00 Cheese 2018-08-06 07:30:00
4 Peter 13:00:00 Nut 2018-08-06 07:30:00
5 Peter 14:00:00 Nut 2018-08-06 07:30:00
6 Peter 15:00:00 Nut 2018-08-06 07:30:00
7 Peter 11:10:00 Nut 2018-08-12 10:30:00
8 Peter 12:10:00 Cheese 2018-08-12 10:30:00
9 Peter 13:10:00 Nut 2018-08-12 10:30:00
我想要这样的df:
Index Name Experiment Start Last Meal in Experiment
0 Peter 2018-08-06 07:30:00 2018-08-06 15:00:00
1 Peter 2018-08-12 10:30:00 2018-08-12 13:10:00
-not enough width-
Count Food Count Nut Count Cheese
7 5 2
3 2 1
要找到“实验中的最后一餐”,这很容易。 我按“时间”(进餐时间)排序,所以最新时间总是在最前面。
df = df.sort_values(by='Time', ascending=False)
然后,通过删除名称和实验开始时间的所有其他重复项,我只保留最近的那些时间。
df = df.drop_duplicates(subset=['Name', 'Experiment Start'])
我这样计算最后一餐的时间:
df['Last Meal in Experiment'] = df['Experiment Start'].dt.floor('D') + df['Time']
现在我应该有类似这样的内容(以及“时间和食物”列):
Index Name Experiment Start Last Meal in Experiment
0 Peter 2018-08-06 07:30:00 2018-08-06 15:00:00
1 Peter 2018-08-12 10:30:00 2018-08-12 13:10:00
但是我不知道如何通过Name的实验开始时间来获取食物数量和奶酪/坚果数量。
在删除重复项之前,我尝试过类似的操作:
df['Count Food'] = df.groupby('Name')['Experiment Start'].transform('count')
但是熊猫有一个错误(新列的格式为dt),我迷路了。
答案 0 :(得分:2)
将GroupBy.size
与unstack
一起使用:
df1= df.groupby(['Name','Experiment Start','Food']).size().unstack()
df1['All'] = df1.sum(axis=1)
或crosstab
:
df1 = pd.crosstab([df['Name'],df['Experiment Start']], df['Food'], margins=True)
df = df.sort_values(by='Time', ascending=False)
df = df.drop_duplicates(subset=['Name', 'Experiment Start'])
df['Last Meal in Experiment'] = df['Experiment Start'].dt.floor('D') + df['Time']
df = df.join(df1, on=['Name','Experiment Start'])
print (df)
Name Time Food Experiment Start Last Meal in Experiment \
Index
6 Peter 15:00:00 Nut 2018-08-06 07:30:00 2018-08-06 15:00:00
9 Peter 13:10:00 Nut 2018-08-12 10:30:00 2018-08-12 13:10:00
Cheese Nut Count
Index
6 2 5 7
9 1 2 3