我有一个包含 3 列(col1、col2 和 col3)的 df,我有一个用户输入可以为列输入一个值,一个、两个或三个,以及任意组合,例如(col1 或 col1&col2,或列 2 和列 3 等)。根据用户输入,我需要选择具有这些值的行。 例如,如果我有下表:
col1 col2 col3
1 3 3
3 4 5
5 2 1
3 4 2
等等,用户只能输入 col2 的值(在本例中为 4),然后我必须显示行(2 和 4),或者如果他们为 col1 输入 (1),则只显示 row(1) ,我的逻辑公式是这样的:
x = input1
y = input2
z = imput3
a = df['col1'] == x and df['col2'] == y and df['col1'] == z
因此 x、y 和 z 可以是基于输入的任何值,包括 nil(nil 表示全部)。
关于如何为这样的公式编写代码有什么建议吗?
使用布尔组合。
a = ((df['col1'] == x) | (x is None)) \
& ((df['col2'] == y) | (y is None)) \
& ((df['col3'] == z) | (z is None))
df1 = df[a]
None
是这里的通配符。
请注意,
&
和 |
不是短路运算符,因此这可能会很昂贵。即使你有一个列的通配符,它仍然会将该列中的所有内容与None
进行比较。更好的方法是动态构建条件。
condition = True
if x is not None:
condition &= df['col1'] == x
if y is not None:
condition &= df['col2'] == y
if z is not None:
condition &= df['col3'] == z
df1 = df[condition]
您可以通过创建列名和条件的字典来更动态地执行此操作。
无论您的数据框有多少列,您都可以拥有一个通用的解决方案。
首先构建列名和查找值的字典,然后可以索引数据框以查找包含这些值的行号,最后将数据框切片以显示必要的行:
import pandas as pd
df = pd.DataFrame(
{
'col1': [1, 3, 5, 3],
'col2': [3, 4, 2, 4],
'col3': [3, 5, 1, 2]
}
)
columns = [f'col{i}' for i in range(1, df.shape[1] + 1)]
query_dict = {}
for c in columns:
try:
query_dict[c] = int(input(f"Enter query for column {c} or Enter to skip: "))
except ValueError:
query_dict[c] = None
rows = []
for k, v in query_dict.items():
rows.extend((df.loc[df[k] == v]).index.values)
df.iloc[rows, :]
我最终使用了以下代码:
mask = True
if x:
mask &= (df['col1'] == x)
if y:
mask &= (df['col2'] == y)
if z:
mask &= (df['col3'] == z)
result = df[mask]