问题:
我有一个基本的python / pandas数据框,其数据单元ID(“ Sarzs_no”)和基于一天中的时间的列(“ Time_of_day”,两个值:昼/夜)。
不幸的是,一天中的时间是唯一的,因为一个单位可以包含两个值(白天和黑夜)。但是,它只能包含一个。
我希望有一个解决方案,可以根据日夜计数多少来更改每个单位的日间时间值。如果它的日计数多于应将其所有值设置为日,反之亦然。
我试图为这个问题制定一个公式:
def dayoftime(napszak_str):
sarzs = row["Sarzs_no"]
day = bfdataf[bfdataf["Sarzs_no"]==sarzs].groupby("Time_of_day").size()[0]
night = bfdataf[bfdataf["Sarzs_no"]==sarzs].groupby("Time_of_day").size()[0]
if day>=night:
return "day"
else:
return "night"
...然后命名为:
bfdataf["new_tod"] = bfdataf["Time_of_day"].apply(dayoftime)
但是不幸的是,我收到“索引超出范围”错误。
能帮我解决这个问题吗?
谢谢!
答案 0 :(得分:2)
您可以通过GroupBy.size
获取每组的数量,使用join
创建DataFrame
,最后使用numpy.where
创建列:
df = bfdataf.groupby(['Sarzs_no','Time_of_day']).size().unstack(fill_value=0)
df = bfdataf.join(df, on='Sarzs_no')
bfdataf['new_tod'] = np.where(df['day'] >= df['night'], 'day', 'night')
另一种解决方案是过滤列,并按transform
每组按sum
获取计数:
days = (bfdataf['Time_of_day'] =='day').groupby(bfdataf['Sarzs_no']).transform('sum')
nights = (bfdataf['Time_of_day'] =='night').groupby(bfdataf['Sarzs_no']).transform('sum')
bfdataf['new_tod'] = np.where( days >= nights, 'day', 'night')
感谢@Jon Clements的另一种解决方案是使用idxmax
作为助手Series
,并通过map
创建新列:
s = bfdataf.groupby(['Sarzs_no','Time_of_day']).size().unstack(fill_value=0).idxmax(axis=1)
bfdataf['new_tod'] = bfdataf['Sarzs_no'].map(s)
print (bfdataf)
Sarzs_no Time_of_day new_tod
0 101/16 day day
1 101/16 day day
2 101/16 day day
3 101/16 day day
4 101/16 day day
5 101/16 night day
6 101/16 night day
7 101/16 night day
8 101/17 night night
9 101/17 night night
10 101/17 night night
11 101/17 night night
12 101/17 night night
13 101/17 night night
14 101/17 night night
15 101/17 night night
16 101/17 night night
17 101/17 night night
18 101/17 day night