设置基于数据框列值的值计数并按

时间:2018-08-26 07:52:34

标签: python pandas dataframe

问题:

我有一个基本的python / pandas数据框,其数据单元ID(“ Sarzs_no”)和基于一天中的时间的列(“ Time_of_day”,两个值:昼/夜)。

enter image description here

不幸的是,一天中的时间是唯一的,因为一个单位可以包含两个值(白天和黑夜)。但是,它只能包含一个。

我希望有一个解决方案,可以根据日夜计数多少来更改每个单位的日间时间值。如果它的日计数多于应将其所有值设置为日,反之亦然。

enter image description here

我试图为这个问题制定一个公式:

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)

但是不幸的是,我收到“索引超出范围”错误。

能帮我解决这个问题吗?

谢谢!

1 个答案:

答案 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