首页 > 解决方案 > 根据列变化选择行

问题描述

假设我们有一个名为 的文件any_csv.csv,其中包含...

A,B,random
1,2,300
3,4,300
5,6,300
1,2,300
3,4,350
8,9,350
4,5,350
5,6,320
7,8,300
3,3,300

我希望保留所有random变化/变化的行。我制作了这个小程序来实现这一点,但是,因为我想了解更多关于 pandas 的信息并且我的程序比我预期的要慢(处理 120 万行日志文件大约需要 130 秒),所以我请求你的帮助.

import pandas as pd
import numpy as np

df = pd.read_csv('any_csv.csv')
mask = np.zeros(len(df.index), dtype=bool)

#   Initializing my current value for comparison purposes.
mask[0] = 1
previous_val = df.iloc[0]['random']
for index, row in df.iterrows():
    if row['random'] != previous_val:
        #   If a variation has been detected, switch to True current, and previous index.
        previous_val = row['random']
        mask[index] = 1
        mask[index - 1] = 1

#   Keeping the last item.
mask[-1] = 1

df = df.loc[mask]
df.to_csv('any_other_csv.csv', index=False)

我想简而言之,我想知道如何在这个自制的 for 循环中应用我的 if,这通常非常慢。

结果 :

A,B,random
1,2,300
1,2,300
3,4,350
4,5,350
5,6,320
7,8,300
3,3,300

标签: pythonpandas

解决方案


您可以利用pd.Series.shift创建布尔值的掩码。布尔掩码指示值何时不同于系列中高于或低于该值的值。

然后,您可以直接将布尔掩码应用于您的数据框。

mask = (df['random'] != df['random'].shift()) | \
       (df['random'] != df['random'].shift(-1))

df = df[mask]

print(df)

   A  B  random
0  1  2     300
3  1  2     300
4  3  4     350
6  4  5     350
7  5  6     320
8  7  8     300
9  3  3     300

推荐阅读