在 how= of resample 中插入新的不存在的列
insert new non-existing column in how= of resample
我正在阅读resample a dataframe with different functions applied to each column?
解决方案是:
frame.resample('1H', how={'radiation': np.sum, 'tamb': np.mean})
如果我想在结果中添加一个不存在的列来存储其他函数的值,比如 count()。在给出的示例中,假设我想计算每个 1H 周期中的行数。
是否可以做到:
frame.resample('1H', how={'radiation': np.sum, 'tamb': np.mean,\
'new_column': count()})
请注意,new_column 不是原始数据框中的现有列。
我问的原因是我需要这样做并且我有一个非常大的数据框并且我不想对原始 df 重新采样两次只是为了在重新采样期间获得计数。
我现在正在尝试上面的方法,似乎需要很长时间(没有语法错误)。不确定 python 是否陷入了某种永远的循环。
更新:
我实施了使用 agg 的建议(非常感谢)。
但是,我在计算第一个聚合器时收到以下错误:
grouped = df.groupby(['name1',pd.TimeGrouper('M')])
return pd.DataFrame(
{'new_col1': grouped['col1'][grouped['col1'] > 0].agg('sum')
...
/Users/blahblah/anaconda/lib/python2.7/site-packages/pandas/core/groupby.pyc in __getitem__(self, key)
521
522 def __getitem__(self, key):
--> 523 raise NotImplementedError('Not implemented: %s' % key)
524
525 def _make_wrapper(self, name):
NotImplementedError: Not implemented: True
当我使用 grouped.apply(foo)
时,以下工作正常。
new_col1 = grp['col1'][grp['col1'] > 0].sum()
resampling
类似于用 TimeGrouper
分组。而 resampling
的
how
参数只允许您为每一列指定一个聚合器,
由 df.groupby(...)
编辑的 GroupBy
对象 return 有一个 agg
方法,可以传递各种函数(例如 mean
、sum
或 count
) 以各种方式聚合组。您可以使用这些结果来构建所需的 DataFrame:
import datetime as DT
import numpy as np
import pandas as pd
np.random.seed(2016)
date_times = pd.date_range(DT.datetime(2012, 4, 5, 8, 0),
DT.datetime(2012, 4, 5, 12, 0),
freq='1min')
tamb = np.random.sample(date_times.size) * 10.0
radiation = np.random.sample(date_times.size) * 10.0
df = pd.DataFrame(data={'tamb': tamb, 'radiation': radiation},
index=date_times)
resampled = df.resample('1H', how={'radiation': np.sum, 'tamb': np.mean})
print(resampled[['radiation', 'tamb']])
# radiation tamb
# 2012-04-05 08:00:00 279.432788 4.549235
# 2012-04-05 09:00:00 310.032188 4.414302
# 2012-04-05 10:00:00 257.504226 5.056613
# 2012-04-05 11:00:00 299.594032 4.652067
# 2012-04-05 12:00:00 8.109946 7.795668
def using_agg(df):
grouped = df.groupby(pd.TimeGrouper('1H'))
return pd.DataFrame(
{'radiation': grouped['radiation'].agg('sum'),
'tamb': grouped['tamb'].agg('mean'),
'new_column': grouped['tamb'].agg('count')})
print(using_agg(df))
产量
new_column radiation tamb
2012-04-05 08:00:00 60 279.432788 4.549235
2012-04-05 09:00:00 60 310.032188 4.414302
2012-04-05 10:00:00 60 257.504226 5.056613
2012-04-05 11:00:00 60 299.594032 4.652067
2012-04-05 12:00:00 1 8.109946 7.795668
注意我的第一个答案建议使用 groupby/apply
:
def using_apply(df):
grouped = df.groupby(pd.TimeGrouper('1H'))
result = grouped.apply(foo).unstack(-1)
result = result.sortlevel(axis=1)
return result[['radiation', 'tamb', 'new_column']]
def foo(grp):
radiation = grp['radiation'].sum()
tamb = grp['tamb'].mean()
cnt = grp['tamb'].count()
return pd.Series([radiation, tamb, cnt], index=['radiation', 'tamb', 'new_column'])
原来这里使用apply
比使用agg
慢多了。如果我们在 1681 行的 DataFrame 上对 using_agg
与 using_apply
进行基准测试:
np.random.seed(2016)
date_times = pd.date_range(DT.datetime(2012, 4, 5, 8, 0),
DT.datetime(2012, 4, 6, 12, 0),
freq='1min')
tamb = np.random.sample(date_times.size) * 10.0
radiation = np.random.sample(date_times.size) * 10.0
df = pd.DataFrame(data={'tamb': tamb, 'radiation': radiation},
index=date_times)
我发现使用 IPython 的 %timeit
函数
In [83]: %timeit using_apply(df)
100 loops, best of 3: 16.9 ms per loop
In [84]: %timeit using_agg(df)
1000 loops, best of 3: 1.62 ms per loop
using_agg
明显快于 using_apply
并且(基于额外的
%timeit
测试)有利于 using_agg
的速度优势随着 len(df)
的增长而增长
成长。
顺便说一句,关于
frame.resample('1H', how={'radiation': np.sum, 'tamb': np.mean,\
'new_column': count()})
除了how
dict不接受不存在的列名的问题外,count
中的括号也有问题。 how
字典中的值应该是函数对象。 count
是一个函数对象,但 count()
是通过调用 count
编辑的值 return。
由于 Python 在 调用函数之前评估参数,因此 count()
在 frame.resample(...)
之前被调用,并且 return 值count()
然后与绑定到 how
参数的字典中的键 'new_column'
相关联。这不是你想要的。
关于更新后的问题:在 调用 groupby/agg
:
之前预先计算您需要的值
而不是
grouped = df.groupby(['name1',pd.TimeGrouper('M')])
return pd.DataFrame(
{'new_col1': grouped['col1'][grouped['col1'] > 0].agg('sum')
...
# ImplementationError since `grouped['col1']` does not implement __getitem__
使用
df['col1_pos'] = df['col1'].clip(lower=0)
grouped = df.groupby(['name1',pd.TimeGrouper('M')])
return pd.DataFrame(
{'new_col1': grouped['col1_pos'].agg('sum')
...
有关预计算为何有助于提高性能的更多信息,请参阅 。
我正在阅读resample a dataframe with different functions applied to each column?
解决方案是:
frame.resample('1H', how={'radiation': np.sum, 'tamb': np.mean})
如果我想在结果中添加一个不存在的列来存储其他函数的值,比如 count()。在给出的示例中,假设我想计算每个 1H 周期中的行数。
是否可以做到:
frame.resample('1H', how={'radiation': np.sum, 'tamb': np.mean,\
'new_column': count()})
请注意,new_column 不是原始数据框中的现有列。
我问的原因是我需要这样做并且我有一个非常大的数据框并且我不想对原始 df 重新采样两次只是为了在重新采样期间获得计数。
我现在正在尝试上面的方法,似乎需要很长时间(没有语法错误)。不确定 python 是否陷入了某种永远的循环。
更新:
我实施了使用 agg 的建议(非常感谢)。
但是,我在计算第一个聚合器时收到以下错误:
grouped = df.groupby(['name1',pd.TimeGrouper('M')])
return pd.DataFrame(
{'new_col1': grouped['col1'][grouped['col1'] > 0].agg('sum')
...
/Users/blahblah/anaconda/lib/python2.7/site-packages/pandas/core/groupby.pyc in __getitem__(self, key)
521
522 def __getitem__(self, key):
--> 523 raise NotImplementedError('Not implemented: %s' % key)
524
525 def _make_wrapper(self, name):
NotImplementedError: Not implemented: True
当我使用 grouped.apply(foo)
时,以下工作正常。
new_col1 = grp['col1'][grp['col1'] > 0].sum()
resampling
类似于用 TimeGrouper
分组。而 resampling
的
how
参数只允许您为每一列指定一个聚合器,
由 df.groupby(...)
编辑的 GroupBy
对象 return 有一个 agg
方法,可以传递各种函数(例如 mean
、sum
或 count
) 以各种方式聚合组。您可以使用这些结果来构建所需的 DataFrame:
import datetime as DT
import numpy as np
import pandas as pd
np.random.seed(2016)
date_times = pd.date_range(DT.datetime(2012, 4, 5, 8, 0),
DT.datetime(2012, 4, 5, 12, 0),
freq='1min')
tamb = np.random.sample(date_times.size) * 10.0
radiation = np.random.sample(date_times.size) * 10.0
df = pd.DataFrame(data={'tamb': tamb, 'radiation': radiation},
index=date_times)
resampled = df.resample('1H', how={'radiation': np.sum, 'tamb': np.mean})
print(resampled[['radiation', 'tamb']])
# radiation tamb
# 2012-04-05 08:00:00 279.432788 4.549235
# 2012-04-05 09:00:00 310.032188 4.414302
# 2012-04-05 10:00:00 257.504226 5.056613
# 2012-04-05 11:00:00 299.594032 4.652067
# 2012-04-05 12:00:00 8.109946 7.795668
def using_agg(df):
grouped = df.groupby(pd.TimeGrouper('1H'))
return pd.DataFrame(
{'radiation': grouped['radiation'].agg('sum'),
'tamb': grouped['tamb'].agg('mean'),
'new_column': grouped['tamb'].agg('count')})
print(using_agg(df))
产量
new_column radiation tamb
2012-04-05 08:00:00 60 279.432788 4.549235
2012-04-05 09:00:00 60 310.032188 4.414302
2012-04-05 10:00:00 60 257.504226 5.056613
2012-04-05 11:00:00 60 299.594032 4.652067
2012-04-05 12:00:00 1 8.109946 7.795668
注意我的第一个答案建议使用 groupby/apply
:
def using_apply(df):
grouped = df.groupby(pd.TimeGrouper('1H'))
result = grouped.apply(foo).unstack(-1)
result = result.sortlevel(axis=1)
return result[['radiation', 'tamb', 'new_column']]
def foo(grp):
radiation = grp['radiation'].sum()
tamb = grp['tamb'].mean()
cnt = grp['tamb'].count()
return pd.Series([radiation, tamb, cnt], index=['radiation', 'tamb', 'new_column'])
原来这里使用apply
比使用agg
慢多了。如果我们在 1681 行的 DataFrame 上对 using_agg
与 using_apply
进行基准测试:
np.random.seed(2016)
date_times = pd.date_range(DT.datetime(2012, 4, 5, 8, 0),
DT.datetime(2012, 4, 6, 12, 0),
freq='1min')
tamb = np.random.sample(date_times.size) * 10.0
radiation = np.random.sample(date_times.size) * 10.0
df = pd.DataFrame(data={'tamb': tamb, 'radiation': radiation},
index=date_times)
我发现使用 IPython 的 %timeit
函数
In [83]: %timeit using_apply(df)
100 loops, best of 3: 16.9 ms per loop
In [84]: %timeit using_agg(df)
1000 loops, best of 3: 1.62 ms per loop
using_agg
明显快于 using_apply
并且(基于额外的
%timeit
测试)有利于 using_agg
的速度优势随着 len(df)
的增长而增长
成长。
顺便说一句,关于
frame.resample('1H', how={'radiation': np.sum, 'tamb': np.mean,\
'new_column': count()})
除了how
dict不接受不存在的列名的问题外,count
中的括号也有问题。 how
字典中的值应该是函数对象。 count
是一个函数对象,但 count()
是通过调用 count
编辑的值 return。
由于 Python 在 调用函数之前评估参数,因此 count()
在 frame.resample(...)
之前被调用,并且 return 值count()
然后与绑定到 how
参数的字典中的键 'new_column'
相关联。这不是你想要的。
关于更新后的问题:在 调用 groupby/agg
:
而不是
grouped = df.groupby(['name1',pd.TimeGrouper('M')])
return pd.DataFrame(
{'new_col1': grouped['col1'][grouped['col1'] > 0].agg('sum')
...
# ImplementationError since `grouped['col1']` does not implement __getitem__
使用
df['col1_pos'] = df['col1'].clip(lower=0)
grouped = df.groupby(['name1',pd.TimeGrouper('M')])
return pd.DataFrame(
{'new_col1': grouped['col1_pos'].agg('sum')
...
有关预计算为何有助于提高性能的更多信息,请参阅