我如何从
获得Idx A B C
2004-04-01 1 1 0
2004-04-02 1 1 0
2004-05-01 0 0 0
2004-05-02 0 0 0
到
Idx A B C
2004-04 2 2 0
2004-05 0 0 0
注意: 如何折叠索引(更具体地说,将索引转换为月份)和每两行?
使用滚动方式是最佳方式吗?
更新 - 我上面的版本很简单,但unutbu的答案似乎不起作用
Time A B
1 2004-01-04 - 2004-01-10 0 0
2 2004-01-11 - 2004-01-17 0 0
3 2004-01-18 - 2004-01-24 0 0
4 2004-01-25 - 2004-01-31 0 0
5 2004-02-01 - 2004-02-07 56 0
6 2004-02-08 - 2004-02-14 67 0
答案 0 :(得分:5)
您可以使用groupby/sum
operation汇总行:
import pandas as pd
import numpy as np
df = pd.DataFrame([('2004-04-01', 1L, 1L, 0L), ('2004-04-02', 1L, 1L, 0L),
('2004-05-01', 0L, 0L, 0L), ('2004-05-02', 0L, 0L, 0L)],
columns=['Idx', 'A', 'B', 'C'])
df['Idx'] = pd.DatetimeIndex(df['Idx'])
您可以按年份和月份进行分组:
print(df.groupby([d.strftime('%Y-%m') for d in df['Idx']]).sum())
# A B C
# 2004-04 2 2 0
# 2004-05 0 0 0
# [2 rows x 3 columns]
或者,按每两行分组:
result = df.groupby(np.arange(len(df))//2).sum()
result.index = df.loc[1::2, 'Idx']
print(result)
# A B C
# Idx
# 2004-04-02 2 2 0
# 2004-05-02 0 0 0
# [2 rows x 3 columns]
注意:使用的是df.loc[1::2, 'Idx']
,而不是df.loc[::2, 'Idx']
,因此聚合行的Idx
将对应于每个组中的第二个日期,而不是第一个日期。
如果您只想要年份和月份,那么您可以使用此列表理解来设置索引:
result.index = [d.strftime('%Y-%m') for d in df.loc[1::2, 'Idx']]
print(result)
# A B C
# 2004-04 2 2 0
# 2004-05 0 0 0
# [2 rows x 3 columns]
但是,在处理日期时,为索引设置DatetimeIndex而不是字符串值索引会更强大。因此,您可能希望保留DatetimeIndex,使用DatetimeIndex执行大部分工作,并在结尾处转换为年月字符串以用于演示目的...
关于更新的问题:
import pandas as pd
import numpy as np
data = np.rec.array([('2004-01-04 - 2004-01-10', 0L, 0L),
('2004-01-11 - 2004-01-17', 0L, 0L),
('2004-01-18 - 2004-01-24', 0L, 0L),
('2004-01-25 - 2004-01-31', 0L, 0L),
('2004-02-01 - 2004-02-07', 56L, 0L),
('2004-02-08 - 2004-02-14', 67L, 0L)],
dtype=[('Time', 'O'), ('A', '<i8'), ('B', '<i8')])
df = pd.DataFrame(data)
让一个时间列保存两个日期会使数据操作更加困难。最好有两个DatetimeIndex
列,Start
和End
:
df[['Start', 'End']] = df['Time'].str.extract('(?P<Start>.+) - (?P<End>.+)')
del df['Time']
df['Start'] = pd.DatetimeIndex(df['Start'])
df['End'] = pd.DatetimeIndex(df['End'])
然后您可以按Start
列进行分组:
print(df.groupby([d.strftime('%Y-%m') for d in df['Start']]).sum())
# A B
# 2004-01 0 0
# 2004-02 123 0
# [2 rows x 2 columns]
或按每两行分组,基本上与之前相同:
result = df.groupby(np.arange(len(df))//2).sum()
result.index = df.loc[1::2, 'Start']
print(result)
# A B
# Start
# 2004-01-11 0 0
# 2004-01-25 0 0
# 2004-02-08 123 0
# [3 rows x 2 columns]