我有一个很大的数据框,这是示例数据:
df['length']
353.216
353.514
273.559
274.199
353.813
354.116
我想遍历行并将i + 1与i行进行比较(如果差异小于2,则该值应保持不变,否则应将整个行过滤掉),我尝试使用布尔索引: diff = abs(df['length']).diff() < 2
,然后df_clean = df[diff]
我想摆脱所有“异常”行。我知道每i + 1行应在+-2范围内。 问题是可以有多于一行。我想摆脱273.559和274.199(在这种情况下),因为它们之间的差小于2,所以我需要对所有行进行两次迭代。对我来说,包括for循环反复遍历似乎不是最好的方法,有什么好的解决方案吗?
编辑:我的输出应如下所示:
df_clean_data ['length']
353.216
353.514
353.813
354.116
先谢谢您 Ziga
答案 0 :(得分:1)
成功的关键是一个功能类似于diff()
:
def mark(x):
global prevX
difr = abs(x - prevX)
result = difr >= 2
if not result:
prevX = x
return result
但是区别在于:
prevX
),
最初包含第一个length
(程序必须
设置它。)x
下的当前prevX
如果差异小于2,那么在这方面,
我们“跳过”要删除的行。第一步是将prevX
设置为第一长度:
prevX = df.loc[0, 'length']
实际处理是通过一条指令执行的:
df.drop(df[df['length'].apply(mark)].index, inplace=True)
一些解释:
df['length'].apply(mark)
生成布尔数组。 True
的意思是“此行
将被删除。”出于指示目的,请单独执行此命令
(删除之前)。df[...].index
生成这些行的索引值列表。df.drop
删除具有给定索引(就位)的行。整个脚本如下所示:
import pandas as pd
def mark(x):
global prevX
difr = abs(x - prevX)
result = difr > 2
if not result:
prevX = x
return result
data={ 'length': [ 353.216, 353.514, 273.559, 274.199, 353.813, 354.116 ] }
df = pd.DataFrame(data)
prevX = df.loc[0, 'length']
df.drop(df[df['length'].apply(mark)].index, inplace=True)
结果是:
length
0 353.216
1 353.514
4 353.813
5 354.116
替代方法:如果要将结果放在另一个数据框中,请删除
inplace=True
并将结果替换为目标变量。
答案 1 :(得分:0)
您必须像这样遍历数据框的行,因为您可以有多行来在2个值之间进行过滤:
ref_row=df.iloc[0] # First line or first value you want to set as reference
valid_rows_indexes = [] # Store valid lines indexes
for index, row in df.iterrows(): # Iterate over rows
if abs(ref_row['length'] - row['length'])<2:
valid_rows_indexes.append(index) # Append valid line index
ref_row=row # Set this row as new reference value
df_clean_data = df.loc[valid_rows_indexes] # Filter dataframe
希望这会有所帮助。
答案 2 :(得分:0)
您的问题尚不清楚,但是无论我了解什么,我都想提出一些建议。
按该列(长度)对DataFrame排序
使用循环检查您的差异
如果要将该记录添加到新的DataFrame中,
使用新的DataFrame
其他方式因为您有Big DataFrame
按该列(长度)对DataFrame排序
创建新列
使用循环检查您的差异
如果您不希望该记录在新列中写np.nan
在新列中删除所有包含np.nan的记录