根据上一列中的值在 Python Dataframe 中构建行
Posted
技术标签:
【中文标题】根据上一列中的值在 Python Dataframe 中构建行【英文标题】:Build rows in Python Dataframe, based on values in previous column 【发布时间】:2020-05-21 04:37:21 【问题描述】:我的输入如下所示:
import datetime as dt
import pandas as pd
some_money = [34,42,300,450,550]
df = pd.DataFrame('TIME': ['2020-01', '2019-12', '2019-11', '2019-10', '2019-09'], \
'MONEY':some_money)
df
产生以下内容:
我想再添加 3 列,获取上个月的 MONEY
值,如下所示(颜色编码用于说明目的):
这是我尝试过的:
prev_period_money = ["m-1", "m-2", "m-3"]
for m in prev_period_money:
df[m] = df["MONEY"] - 10 #well, it "works", but it gives df["MONEY"]- 10...
TIME
列已排序,因此不必关心它。 (但如果有人展示“魔法”,能够从中获取数据,那就太好了。)
【问题讨论】:
【参考方案1】:用于pandas 0.24+ fill_value=0
in Series.shift
,然后也是正确的整数列:
for x in range(1,4):
df[f"m-x"] = df["MONEY"].shift(periods=-x, fill_value=0)
print (df)
TIME MONEY m-1 m-2 m-3
0 2020-01 34 42 300 450
1 2019-12 42 300 450 550
2 2019-11 300 450 550 0
3 2019-10 450 550 0 0
4 2019-09 550 0 0 0
对于低于 0.24 的 pandas,需要替换缺失值并转换为整数:
for x in range(1,4):
df[f"m-x"] = df["MONEY"].shift(periods=-x).fillna(0).astype(int)
【讨论】:
语法短得多。 每列的fillna(0)
实际上是相当重要的,否则df = df.fillna(0)
可能会“污染”整个表格。【参考方案2】:
如果你使用shift
就很简单
这会给你想要的输出:
df["m-1"] = df["MONEY"].shift(periods=-1)
df["m-2"] = df["MONEY"].shift(periods=-2)
df["m-3"] = df["MONEY"].shift(periods=-3)
df = df.fillna(0)
这只有在订购时才有效。否则,您必须先订购。
【讨论】:
如果您知道“移位”存在......我期待“偏移”作为一个术语。 :) 谢谢 :) @Vityata 这是真的。知识就是力量。顺便说一句,你也可以将它集成到你的 for 循环中,而不是三行。【参考方案3】:我的建议:使用带有 shift 函数的列表推导来获取三列,将它们连接到列上,然后再次将其连接到原始数据帧
(pd.concat([df,pd.concat([df.MONEY.shift(-i) for i in
range(1,4)],axis=1)],
axis=1)
.fillna(0)
)
TIME MONEY MONEY MONEY MONEY
0 2020-01 34 42.0 300.0 450.0
1 2019-12 42 300.0 450.0 550.0
2 2019-11 300 450.0 550.0 0.0
3 2019-10 450 550.0 0.0 0.0
4 2019-09 550 0.0 0.0 0.0
【讨论】:
【参考方案4】:import pandas as pd
columns = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov"]
some_money = [34,42,300,450,550]
df = pd.DataFrame('TIME': ['2020-01', '2019-12', '2019-11', '2019-10', '2019-09'], 'MONEY':some_money)
prev_period_money = ["m-1", "m-2", "m-3"]
count = 1
for m in prev_period_money:
df[m] = df['MONEY'].iloc[count:].reset_index(drop=True)
count += 1
df = df.fillna(0)
输出:
TIME MONEY m-1 m-2 m-3
0 2020-01 34 42.0 300.0 450.0
1 2019-12 42 300.0 450.0 550.0
2 2019-11 300 450.0 550.0 0.0
3 2019-10 450 550.0 0.0 0.0
4 2019-09 550 0.0 0.0 0.0
【讨论】:
索引的删除和重置是什么概念? @Vityatailoc
正在收集带有原始索引的行以上是关于根据上一列中的值在 Python Dataframe 中构建行的主要内容,如果未能解决你的问题,请参考以下文章