我是Pandas的新手。我有一个看起来像这样的数据框:
days rainfall
1 3.51
2 1.32
3 0
4 0
5 0
6 0
7 0
8 0
9 0.03
10 0
11 0
12 0.17
13 0.23
14 0.02
15 0
16 0
17 0
18 0.03
19 0.02
20 0
21 0
我想添加一列(我们称其为“累积”),以显示每周的累积降雨值。换句话说,我要计算前7天(1-7),然后是第二组7天(8-14)的累积值,依此类推。
最终产品看起来像这样:
days rainfall cumulative
1 3.51 4.83
2 1.32 0.45
3 0 0.05
4 0
5 0
6 0
7 0
8 0
9 0.03
10 0
11 0
12 0.17
13 0.23
14 0.02
15 0
16 0
17 0
18 0.03
19 0.02
20 0
21 0
到目前为止,我已经尝试用rolling
来调用sum
,但是我没有得到想要的东西。
df['cumulative']=df['rainfall'].rolling(min_periods=7, window=7).sum()
感谢任何提示或建议!
答案 0 :(得分:1)
您可以这样做:
import pandas as pd
df = pd.DataFrame([
[ 1, 3.51],
[ 2, 1.32],
[ 3, 0],
[ 4, 0],
[ 5, 0],
[ 6, 0],
[ 7, 0],
[ 8, 0],
[9, 0.03],
[10, 0],
[11, 0],
[12, 0.17],
[13, 0.23],
[14, 0.02],
[15, 0],
[16, 0],
[17, 0],
[18, 0.03],
[19, 0.02],
[20, 0],
[21, 0]], columns=['days', 'rainfall'])
result = df['rainfall'].groupby((df['days'] - 1) // 7).sum().reset_index(drop=True)
print(result)
# In [418]: %paste -q
# 0 4.83
# 1 0.45
# 2 0.05
# Name: rainfall, dtype: float64
答案 1 :(得分:1)
如果我对您的理解正确,那么您需要GroupBy.transform
:
# create groups of each 7 days with floordivision
grps = df['days'].sub(1).floordiv(7)
# get the cumulative sum per group
df['cumsum'] = df.groupby(grps)['rainfall'].transform('sum')
days rainfall cumsum
0 1 3.51 4.83
1 2 1.32 4.83
2 3 0.00 4.83
3 4 0.00 4.83
4 5 0.00 4.83
5 6 0.00 4.83
6 7 0.00 4.83
7 8 0.00 0.45
8 9 0.03 0.45
9 10 0.00 0.45
10 11 0.00 0.45
11 12 0.17 0.45
12 13 0.23 0.45
13 14 0.02 0.45
14 15 0.00 0.05
15 16 0.00 0.05
16 17 0.00 0.05
17 18 0.03 0.05
18 19 0.02 0.05
19 20 0.00 0.05
20 21 0.00 0.05
答案 2 :(得分:0)
编辑:没有DateTime索引的另一种方法是pd.cut()。
df.groupby(pd.cut(df.days, bins=3,
precision=0))["rainfall"].sum()
days
(1.0, 8.0] 4.83
(8.0, 14.0] 0.45
(14.0, 21.0] 0.05
cut方法允许您指定频率范围来合并值。
pd.cut(df.days, bins=3)
是一种说法,即“获取Series df [“ days”]并将其分成三个大块”。如果仅运行该代码,则会看到:
0 (1.0, 8.0]
1 (1.0, 8.0]
2 (1.0, 8.0]
.
.
.
19 (14.0, 21.0]
20 (14.0, 21.0]
它将用其所属的bin标记DataFrame中的每一行。然后,您可以将其用作groupby语句中的参数,就像其他任何列属性一样,并应用聚合函数。
将[“ rainfall”]放在groupby语句之外是一种表达方式,“这是我想要加和的列”(即,不加总天数)。 如果更直观,则可以先编写它。 (这很令人高兴,也令人沮丧,熊猫不仅拥有一种而且只有一种正确的做事方式。)
df["rainfall"].groupby(...)
原始答案:
对于汇总统计信息,可以使用pd.resample()。这是一个DateTime索引方法(我不得不在这里强制使用,但通常情况下,天气时间戳记会更多)。
df.resample("W").sum()["rainfall"]
是将天数缩减为几周并汇总值的代码。
在这种情况下,我从字典构造了一个DataFrame并将索引转换为DateTime格式以使用resample方法:
df = pd.DataFrame(
data={
"days": (list(range(1,22))),
"rainfall": [3.51,
1.32, 0, 0, 0, 0, 0, 0, 0.03,
0, 0, 0.17, 0.23, 0.02, 0, 0,
0, 0.03, 0.02, 0, 0]},
index=pd.to_datetime(list(range(1,22)), format="%d",
errors="coerce"))
那会让你:
1900-01-07 4.83
1900-01-14 0.45
1900-01-21 0.05
Freq: W-SUN, Name: rainfall, dtype: float64
同样,您希望适当地调整年和月,但是重新采样的好处是您可以轻松地按预定义的时间间隔(周,天,分钟等)和自定义跨度进行汇总。