循环遍历 Pandas 数据帧并根据条件复制到新数据帧
Posted
技术标签:
【中文标题】循环遍历 Pandas 数据帧并根据条件复制到新数据帧【英文标题】:Loop through Pandas dataframe and copying to a new dataframe based on a condition 【发布时间】:2020-11-21 12:56:36 【问题描述】:我有一个数据框 df
,其中包含 6000 多行数据,日期时间索引采用 YYYY-MM-DD
形式,列 ID
、water_level
和 change
。
我想:
-
遍历
change
列中的每个值并确定转折点
当我找到一个转折点时,将包括索引在内的整行数据复制到一个新的数据帧中,例如turningpoints_df
对于循环中确定的每个新转折点,将该行数据添加到我的新数据框turningpoints_df
,这样我最终会得到如下结果:
ID water_level change
date
2000-10-01 2 5.5 -0.01
2000-12-13 40 10.0 0.02
2001-02-10 150 1.1 -0.005
2001-07-29 201 12.4 0.01
... ... ... ...
我正在考虑采用定位方法,例如(纯粹是说明性的):
turningpoints_df = pd.DataFrame(columns = ['ID', 'water_level', 'change'])
for i in range(len(df['change'])):
if [i-1] < 0 and [i+1] > 0:
#this is a min point and take this row and copy to turningpoints_df
elif [i-1] > 0 and [i+1] < 0:
#this is a max point and take this row and copy to turningpoints_df
else:
pass
我的问题是,我不确定如何对照之前和之后的值检查change
列中的每个值,然后在满足条件时如何将该行数据提取到新的 df 中.
【问题讨论】:
预期输出之前的数据是什么样的? IE。输入是什么? 分享源 df 的样本会很有用 (df..loc[n:m].to_dict()
)。是一个转折点,与 date 和 ID 无关。即只是df中数据的顺序?
@RobRaymond 这只是水位的每日时间序列,最后有一个额外的列“变化”记录与上一个条目的水位差异
【参考方案1】:
听起来您想使用 DataFrame 的 shift
方法。
# shift values down by 1:
df[change_down] = df[change].shift(1)
# shift values up by 1:
df[change_up] = df[change].shift(-1)
然后您应该能够比较每一行的值并继续您想要实现的任何目标..
for row in df.iterrows():
*check conditions here*
【讨论】:
【参考方案2】:使用一些 NumPy 功能,让您可以roll()
向前或向后进行一系列操作。然后将 prev 和 next 放在同一行上,这样就可以使用一个简单的函数来apply()
你的逻辑,因为一切都在同一行上。
from decimal import *
import numpy as np
d = list(pd.date_range(dt.datetime(2000,1,1), dt.datetime(2010,12,31)))
df = pd.DataFrame("date":d, "ID":[random.randint(1,200) for x in d],
"water_level":[round(Decimal(random.uniform(1,13)),2) for x in d],
"change":[round(Decimal(random.uniform(-0.05, 0.05)),3) for x in d])
# have ref to prev and next, just apply logic
def turningpoint(r):
r["turningpoint"] = (r["prev_change"] < 0 and r["next_change"] > 0) or \
(r["prev_change"] > 0 and r["next_change"] < 0)
return r
# use numpy to shift "change" so have prev and next on same row as new columns
# initially default turningpoint boolean
df = df.assign(prev_change=np.roll(df["change"],1),
next_change=np.roll(df["change"],-1),
turningpoint=False).apply(turningpoint, axis=1).drop(["prev_change", "next_change"], axis=1)
# first and last rows cannot be turning points
df.loc[0:0,"turningpoint"] = False
df.loc[df.index[-1], "turningpoint"] = False
# take a copy of all rows that are turningpoints into new df with index
df_turningpoint = df[df["turningpoint"]].copy()
df_turningpoint
【讨论】:
谢谢!这似乎运作良好,我经常忘记在处理数据帧时使用 NumPy 功能。我现在想知道是否可以为每个转折点分配一个“最小”和“最大”标识符,以便轻松执行后续计算以上是关于循环遍历 Pandas 数据帧并根据条件复制到新数据帧的主要内容,如果未能解决你的问题,请参考以下文章
python 将csv文件转换为Pandas数据帧并遍历其行的函数
循环遍历excel文件做一些事情并将它们保存到新文件夹python pandas