pandas 按链中的列索引过滤 Dataframe ,而不使用列名或表名

p1tboqfb  于 2023-01-28  发布在  其他
关注(0)|答案(3)|浏览(179)

生成示例 Dataframe

import random
import string
import numpy as np
df = pd.DataFrame(
    columns=[random.choice(string.ascii_uppercase) for i in range(5)],
    data=np.random.rand(10,5))
df
          V         O         C         X         E
0  0.060255  0.341051  0.288854  0.740567  0.236282
1  0.933778  0.393021  0.547383  0.469255  0.053089
2  0.994518  0.156547  0.917894  0.070152  0.201373
3  0.077694  0.685540  0.865004  0.830740  0.605135
4  0.760294  0.838441  0.905885  0.146982  0.157439
5  0.116676  0.340967  0.400340  0.293894  0.220995
6  0.632182  0.663218  0.479900  0.931314  0.003180
7  0.726736  0.276703  0.057806  0.624106  0.719631
8  0.677492  0.200079  0.374410  0.962232  0.915361
9  0.061653  0.984166  0.959516  0.261374  0.361677

现在我想使用第一列中的值来过滤 Dataframe ,但是由于我大量使用链接(例如df.T.replace(0, np.nan).pipe(np.log2).mean(axis=1).fillna(0).pipe(func)),因此我需要一个更紧凑的符号来表示操作。

df[df.iloc[:, 0] < 0.5]
          V         O         C         X         E
0  0.060255  0.341051  0.288854  0.740567  0.236282
3  0.077694  0.685540  0.865004  0.830740  0.605135
5  0.116676  0.340967  0.400340  0.293894  0.220995
9  0.061653  0.984166  0.959516  0.261374  0.361677

但是这种笨拙的冗余语法对于链接来说太可怕了,我想用.query()来代替它,通常你会使用像df.query('V < 0.5')这样的列名,但是在这里我希望能够通过列索引号而不是名称来查询表,所以在这个例子中,我故意将列名随机化,也不能在df.query('@df[0] < 0.5')这样的查询中使用表名,因为在长链中,中间结果没有名称。
我希望有一些语法,比如df.query('_[0] < 0.05'),在那里我可以用一些符号_来引用源表。

2izufjch

2izufjch1#

您可以在df. query中使用f字符串表示法:

df.query(f'{df.columns[0]} < .5')

输出:

J         M         O         R         N
3  0.114554  0.131948  0.650307  0.672486  0.688872
4  0.272368  0.745900  0.544068  0.504299  0.434122
6  0.418988  0.023691  0.450398  0.488476  0.787383
7  0.040440  0.220282  0.263902  0.660016  0.955950

在python 3.8+中使用"walrus"运算符进行更新

我们试试看:

((dfout := df.T.replace(0, np.nan).pipe(np.log2).mean(axis=1).fillna(0).to_frame(name='values'))
             .query(f'{dfout.columns[0]} > -2'))

输出:

values
N -1.356779
O -1.202353
M -1.591623
T -1.557801
n3schb8v

n3schb8v2#

你可以在loc中使用lambda函数,它传入 Dataframe ,然后你可以使用iloc作为位置索引。

df.loc[lambda x: x.iloc[:, 0] > 0.5]

这应该在方法链中起作用。

yqlxgs2m

yqlxgs2m3#

对于具有索引的单列:

df.query(f"{df.columns[0]}<0.5")

          V         O         C         X         E
0  0.060255  0.341051  0.288854  0.740567  0.236282
3  0.077694  0.685540  0.865004  0.830740  0.605135
5  0.116676  0.340967  0.400340  0.293894  0.220995
9  0.061653  0.984166  0.959516  0.261374  0.361677

对于具有索引的多列:

idx = [0,1]
col = df.columns[np.r_[idx]]
val = 0.5
query = ' and '.join([f"{i} < {val}" for i in col])
# V < 0.5 and O < 0.5
print(df.query(query))

          V         O         C         X         E
0  0.060255  0.341051  0.288854  0.740567  0.236282
5  0.116676  0.340967  0.400340  0.293894  0.220995

相关问题