Pandas Python的熊猫,分组
我有一个数据集,每个时间戳由多个元组组成,每个元组都有一个计数。每个时间戳上可能存在不同的元组。我想把这些放在5分钟的箱子里,并为每个独特的元组添加计数。有没有一个很好的干净的方法来使用熊猫小组 它们的形式如下: (u'67.163.47.231',u'8.27.82.254',50186,80,6137565195000),2) 这当前是一个列表,带有6元组(最后一个条目是时间戳),然后是计数 每个时间戳将有一个5元组的集合: (5元组)、t时间戳、计数,例如(仅用于一个时间戳) 或转换为:Pandas Python的熊猫,分组,pandas,Pandas,我有一个数据集,每个时间戳由多个元组组成,每个元组都有一个计数。每个时间戳上可能存在不同的元组。我想把这些放在5分钟的箱子里,并为每个独特的元组添加计数。有没有一个很好的干净的方法来使用熊猫小组 它们的形式如下: (u'67.163.47.231',u'8.27.82.254',50186,80,6137565195000),2) 这当前是一个列表,带有6元组(最后一个条目是时间戳),然后是计数 每个时间戳将有一个5元组的集合: (5元组)、t时间戳、计数,例如(仅用于一个时间戳) 或转换为:
In [231]: df = DataFrame ( { 'key1' : [ (u'71.57.43.240', u'8.27.82.254', 33108, 80, 6), (u'67.163.47.231', u'8.27.82.254', 50186, 80, 6) ], 'data1' : np.array((1,2)),
.....: 'data2': np.array(( datetime.utcfromtimestamp(1377565195),datetime.utcfromtimestamp(1377565195) )) })
In [232]: df
Out[232]:
data1 data2 key1
0 1 2013-08-27 00:59:55 (71.57.43.240, 8.27.82.254, 33108, 80, 6)
1 2 2013-08-27 00:59:55 (67.163.47.231, 8.27.82.254, 50186, 80, 6)
Here's a simpler example:
time count city
00:00:00 1 Montreal
00:00:00 2 New York
00:00:00 1 Chicago
00:01:00 2 Montreal
00:01:00 3 New York
after bin-ing
time count city
00:05:00 3 Montreal
00:05:00 5 New York
00:05:00 1 Chicago
下面是一些似乎很有效的方法:
times = [ parse('00:00:00'), parse('00:00:00'), parse('00:00:00'), parse('00:01:00'), parse('00:01:00'),
parse('00:02:00'), parse('00:02:00'), parse('00:03:00'), parse('00:04:00'), parse('00:05:00'),
parse('00:05:00'), parse('00:06:00'), parse('00:06:00') ]
cities = [ 'Montreal', 'New York', 'Chicago', 'Montreal', 'New York',
'New York', 'Chicago', 'Montreal', 'Montreal', 'New York', 'Chicago', 'Montreal', 'Chicago']
counts = [ 1, 2, 1, 2, 3, 1, 1, 1, 2, 2, 2, 1, 1]
frame = DataFrame( { 'city': cities, 'time': times, 'count': counts } )
In [150]: frame
Out[150]:
city count time
0 Montreal 1 2013-09-07 00:00:00
1 New York 2 2013-09-07 00:00:00
2 Chicago 1 2013-09-07 00:00:00
3 Montreal 2 2013-09-07 00:01:00
4 New York 3 2013-09-07 00:01:00
5 New York 1 2013-09-07 00:02:00
6 Chicago 1 2013-09-07 00:02:00
7 Montreal 1 2013-09-07 00:03:00
8 Montreal 2 2013-09-07 00:04:00
9 New York 2 2013-09-07 00:05:00
10 Chicago 2 2013-09-07 00:05:00
11 Montreal 1 2013-09-07 00:06:00
12 Chicago 1 2013-09-07 00:06:00
frame['time_5min'] = frame['time'].map(lambda x: pd.DataFrame([0],index=pd.DatetimeIndex([x])).resample('5min').index[0])
In [152]: frame
Out[152]:
city count time time_5min
0 Montreal 1 2013-09-07 00:00:00 2013-09-07 00:00:00
1 New York 2 2013-09-07 00:00:00 2013-09-07 00:00:00
2 Chicago 1 2013-09-07 00:00:00 2013-09-07 00:00:00
3 Montreal 2 2013-09-07 00:01:00 2013-09-07 00:00:00
4 New York 3 2013-09-07 00:01:00 2013-09-07 00:00:00
5 New York 1 2013-09-07 00:02:00 2013-09-07 00:00:00
6 Chicago 1 2013-09-07 00:02:00 2013-09-07 00:00:00
7 Montreal 1 2013-09-07 00:03:00 2013-09-07 00:00:00
8 Montreal 2 2013-09-07 00:04:00 2013-09-07 00:00:00
9 New York 2 2013-09-07 00:05:00 2013-09-07 00:05:00
10 Chicago 2 2013-09-07 00:05:00 2013-09-07 00:05:00
11 Montreal 1 2013-09-07 00:06:00 2013-09-07 00:05:00
12 Chicago 1 2013-09-07 00:06:00 2013-09-07 00:05:00
In [153]: df = frame.groupby(['time_5min', 'city']).aggregate('sum')
In [154]: df
Out[154]:
count
time_5min city
2013-09-07 00:00:00 Chicago 2
Montreal 6
New York 6
2013-09-07 00:05:00 Chicago 3
Montreal 1
New York 2
In [155]: df.reset_index(1)
Out[155]:
city count
time_5min
2013-09-07 00:00:00 Chicago 2
2013-09-07 00:00:00 Montreal 6
2013-09-07 00:00:00 New York 6
2013-09-07 00:05:00 Chicago 3
2013-09-07 00:05:00 Montreal 1
2013-09-07 00:05:00 New York 2
如果只想将每个唯一元组的计数相加,只需按groupby
key1
:
df.groupby('key1').aggregate('sum')
如果要对每个时间步和每个唯一元组执行此操作,可以通过以下方式为分组提供多个列:
df.groupby(['data2', 'key1']).aggregate('sum')
如果必须在一个5分钟箱中组合不同的时间步长,一种可能的方法是将时间戳四舍五入到5分钟,然后分组:
df['data2_5min'] = (np.ceil(df['data2'].values.astype('int64')/(5.0*60*1000000000))*(5.0*60*1000000000)).astype('int64').astype('M8[ns]')
df.groupby(['data2_5min', 'key1']).aggregate('sum')
如果希望保留一些原始时间戳(但如果要将它们装箱,则必须选择哪个时间戳),可以指定要应用于各个列的函数。以第一个为例:
df2 = df.groupby(['data2_5min', 'key1']).aggregate({'data1':'sum', 'data2':'first'})
df2.reset_index(0, drop=True).set_index('data2', append=True)
如果您只想在5分钟内重新采样并添加计数,而不考虑关键点,您只需执行以下操作:
df.set_index('data2', inplace=True)
df.resample('5min', 'sum')
如果将日期设置为索引,则可以使用TimeGrouper(它允许您按5分钟的间隔进行分组): 然后,您可以使用nunique计算每5分钟间隔内的唯一项目数:
In [14]: g['key1'].nunique()
Out[14]:
2013-08-27 00:55:00 2
dtype: int64
如果要查找每个元组的计数,可以使用value\u counts:
In [15]: g['key1'].apply(pd.value_counts)
Out[15]:
2013-08-27 00:55:00 (71.57.43.240, 8.27.82.254, 33108, 80, 6) 1
(67.163.47.231, 8.27.82.254, 50186, 80, 6) 1
dtype: int64
注意:这是一个具有多索引的系列(使用reset_索引使其成为数据帧)
您可能想给这些更具信息性的列名:)
更新:我之前入侵过get,请参见编辑历史。您能给出整个数据帧的简短示例数据吗?[(u'71.57.43.240',u'8.27.82.254',33108,80,61377595000),1),((u'67.163.47.231',u'8.27.82.254',50186,80,6137565195000),2),(u'8.27.82.254',u'98.206.29.242',25159 80,61375195000),1)((u'69.66.66.156.156.250,”u'69.66.66.56.56.56.250,”u'8.27.82.82.82.254、59274、80、6、6、6、6、6、6、6、6、8.66.66.66.56.56、59.69.69.66、59.69、59、59、59、78、80、60、6、6、6、6、6、59276、57575757575757565656565656565656565、515、5、5、5、5、5、5、5、500、5、500、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、5、3、3、3、3、3、3、3、3)、3、3、3、3、3、3、3、3、3、1377565195000),1),您可以编辑您的问题以将其包括在内,而不是作为注释。本例中的时间戳在哪里?6元组中的最后一个条目您是否已将其放在熊猫数据框中?看起来如何(元组是一列)?键是唯一的(但可能不会在每个时间步都出现)。我想添加数据1(计数)每一个唯一的键都放在一起,然后把它们放进5分钟的箱子里,所以第二种方法就是你想要的?或者还没有?这看起来比我的好,但是它没有分成5分钟的间隔(我想你可以用四舍五入的时间做一个列?@Andy是的,这就是我尝试的(四舍五入的时间),但我不清楚是否需要它(可能所有的时间都是5分钟,然后它只是一个简单的groupby)@Andy Lol,另一个破解方法:-)
df['data2'].map(lambda x:pd.DataFrame([0],index=pd.DatetimeIndex([x])。重采样('5min').index[0])
I♥ get_dummies,但是对于get_dummies(x).sum()
lol这是TimeGrouper的值计数技巧!但是我认为他想“添加计数”(这是一个现有列),而不是“计算唯一键”是的,它应该在文档中!(也似乎很遗憾你不能对一个列这么做…)但可以肯定的是,计数需要更精确added@StephenThomas我不明白你的意思,这算是发生的次数。如果这不是你想要的,你能在你的问题中包括你想要的结果吗?
In [14]: g['key1'].nunique()
Out[14]:
2013-08-27 00:55:00 2
dtype: int64
In [15]: g['key1'].apply(pd.value_counts)
Out[15]:
2013-08-27 00:55:00 (71.57.43.240, 8.27.82.254, 33108, 80, 6) 1
(67.163.47.231, 8.27.82.254, 50186, 80, 6) 1
dtype: int64
In [16]: g['key1'].apply(pd.value_counts).reset_index(1)
Out[16]:
level_1 0
2013-08-27 00:55:00 (71.57.43.240, 8.27.82.254, 33108, 80, 6) 1
2013-08-27 00:55:00 (67.163.47.231, 8.27.82.254, 50186, 80, 6) 1