根据 pandas 列值加速删除行

speed up drop rows base on pandas column values

我有一个非常大的 pandas 数据框,看起来像

df = pd.DataFrame({"Station": [2, 2, 2, 5, 5, 5, 6, 6],
                   "Day": [1, 2, 3, 1, 2, 3, 1, 2],
                   "Temp": [-7.0, 2.7, -1.3, -1.9, 0.2, 0.5, 1.3, 6.4]})

并且我想尽可能高效(快速)地过滤掉所有行,这些行没有恰好有 n 行具有特定的 'Station' 值。

stations =  pd.unique(df['Station'])
n = 3

def complete(temp):
    for k in range(len(stations)):
        if len(temp[temp['Station']== stations[k]].Temp) != n:
            temp.drop(temp.index[temp['Station'] == stations[k]], inplace=True)

我一直在研究使用@jit(nopython=True) 或 Cython 沿着这个 enhance pandas tutorial 的思路,但在我发现的示例中,这些列是相互分开处理的。我想知道,以某种方式使用@jit 创建一个仅包含我想要的行的 v = df['Station'] 新列表然后使用 df = df[df.Station.isin(v)] 过滤掉整个数据的行的最快方法是什么框架还是有更好的方法?

您可以 groupby“Station”和转换 count 方法并将计数与 n 进行比较以创建布尔系列。然后使用此掩码过滤相关行:

n=3
msk = df.groupby('Station')['Temp'].transform('count').eq(n)
df = df[msk]

输出:

   Station  Day  Temp
0        2    1  -7.0
1        2    2   2.7
2        2    3  -1.3
3        5    1  -1.9
4        5    2   0.2
5        5    3   0.5

使用value_counts:

out = df[df['Station'].isin(df['Station'].value_counts().loc[lambda x: x==n].index)]
print(out)

# Output
   Station  Day  Temp
0        2    1  -7.0
1        2    2   2.7
2        2    3  -1.3
3        5    1  -1.9
4        5    2   0.2
5        5    3   0.5

value_counts的结果:

>>> df['Station'].value_counts()
2    3
5    3
6    2
Name: Station, dtype: int64