有没有办法循环遍历 pandas 数据框并根据条件删除 windows 行?
Is there a way to loop through pandas dataframe and drop windows of rows dependent on condition?
- 问题总结 - 我有一个约 10,000 行的数据框。有些行包含我想消除的数据偏差,这些偏差与在特定温度下进行的观察有关(其中一个数据列)。
- 我试过的方法 - 我的想法是,删除不良数据行的最简单方法是遍历温度区间,找到小于的最大索引比每个温度间隔观测值,并使用 df.drop 函数删除该索引周围的 window 行。在观察到不良数据的每个温度间隔之间,我重置了数据帧的索引。 然而,它似乎完全不稳定!!有时它几乎可以工作,有时它会抛出关键错误。我认为我的问题可能在于“就地”使用数据框,但我看不到其他方法。
- 示例代码:
这是一个带有合成数据框的示例和一个使用与我尝试过的相同原理的函数。请注意,我已尝试使用 .loc 和 .iloc 进行不同的演绎(在下面注释掉)。
#Create synthetic dataframe
import pandas as pd
import numpy as np
temp_series = pd.Series(range(25, 126, 1))
temp_noise = np.random.rand(len(temp_series))*3
df = pd.DataFrame({'temp':(temp_series+temp_noise), 'data':(np.random.rand(len(temp_series)))*400})
#calculate length of original and copy original because function works in place.
before_length = len(df)
df_dup = df
temp_intervals = [50, 70, 92.7]
window = 5
从这里开始,运行 一个基于数据框 (df)、温度观测值 (temp_intervals) 和 window 大小 (window) 的函数:
def remove_window(df, intervals, window):
'''Loop through the temperature intervals to define a window of indices around given temperatures in the dataframe to drop. Drop the window of indices in place and reset the index prior to moving to the next interval.
'''
def remove_window(df, intervals, window):
for temp in intervals[0:len(intervals)]:
#Find index where temperature first crosses the interval input
cent_index = max(df.index[df['temp']<=temp].tolist())
#Define window of indices to remove from the df
drop_indices = list(range(cent_index-window, cent_index+window))
#Use df.drop
df.drop(drop_indices, inplace=True)
df.reset_index(drop=True)
return df
那么,这是我定义的函数有问题还是 df.drop 有问题?
谢谢,
布拉德
重复删除部分数据帧并跟踪您正在做的事情可能会很棘手。一种更简洁的方法是跟踪要在循环内删除哪些行,但只在循环外一次性删除它们。这也应该更快。
def remove_window(df, intervals, window):
# Create a Boolean array indicating which rows to keep
keep_row = np.repeat(True, len(df))
for temp in intervals[0:len(intervals)]:
# Find index where temperature first crosses the interval input
cent_index = max(df.index[df['temp']<=temp].tolist())
# Define window of indices to remove from the df
keep_row[range(cent_index - window, cent_index + window)] = False
# Delete all unwanted rows at once, outside the loop
df = df[keep_row]
df.reset_index(drop=True, inplace=True)
return df
- 问题总结 - 我有一个约 10,000 行的数据框。有些行包含我想消除的数据偏差,这些偏差与在特定温度下进行的观察有关(其中一个数据列)。
- 我试过的方法 - 我的想法是,删除不良数据行的最简单方法是遍历温度区间,找到小于的最大索引比每个温度间隔观测值,并使用 df.drop 函数删除该索引周围的 window 行。在观察到不良数据的每个温度间隔之间,我重置了数据帧的索引。 然而,它似乎完全不稳定!!有时它几乎可以工作,有时它会抛出关键错误。我认为我的问题可能在于“就地”使用数据框,但我看不到其他方法。
- 示例代码: 这是一个带有合成数据框的示例和一个使用与我尝试过的相同原理的函数。请注意,我已尝试使用 .loc 和 .iloc 进行不同的演绎(在下面注释掉)。
#Create synthetic dataframe
import pandas as pd
import numpy as np
temp_series = pd.Series(range(25, 126, 1))
temp_noise = np.random.rand(len(temp_series))*3
df = pd.DataFrame({'temp':(temp_series+temp_noise), 'data':(np.random.rand(len(temp_series)))*400})
#calculate length of original and copy original because function works in place.
before_length = len(df)
df_dup = df
temp_intervals = [50, 70, 92.7]
window = 5
从这里开始,运行 一个基于数据框 (df)、温度观测值 (temp_intervals) 和 window 大小 (window) 的函数:
def remove_window(df, intervals, window):
'''Loop through the temperature intervals to define a window of indices around given temperatures in the dataframe to drop. Drop the window of indices in place and reset the index prior to moving to the next interval.
'''
def remove_window(df, intervals, window):
for temp in intervals[0:len(intervals)]:
#Find index where temperature first crosses the interval input
cent_index = max(df.index[df['temp']<=temp].tolist())
#Define window of indices to remove from the df
drop_indices = list(range(cent_index-window, cent_index+window))
#Use df.drop
df.drop(drop_indices, inplace=True)
df.reset_index(drop=True)
return df
那么,这是我定义的函数有问题还是 df.drop 有问题?
谢谢, 布拉德
重复删除部分数据帧并跟踪您正在做的事情可能会很棘手。一种更简洁的方法是跟踪要在循环内删除哪些行,但只在循环外一次性删除它们。这也应该更快。
def remove_window(df, intervals, window):
# Create a Boolean array indicating which rows to keep
keep_row = np.repeat(True, len(df))
for temp in intervals[0:len(intervals)]:
# Find index where temperature first crosses the interval input
cent_index = max(df.index[df['temp']<=temp].tolist())
# Define window of indices to remove from the df
keep_row[range(cent_index - window, cent_index + window)] = False
# Delete all unwanted rows at once, outside the loop
df = df[keep_row]
df.reset_index(drop=True, inplace=True)
return df