在数据框中查找值并在相应列中查找交叉引用值

时间:2019-02-26 06:24:17

标签: python dataframe indexing

我有一个数据框,如下所示:

Index   X_1  X_2  X_3  W_1   W_2   W_3
1       IEZ  XOP  ABC  0.42  0.18  0.40
2       PXJ  ABC  XES  0.47  0.12  0.41
3       ABC  RYE  PXE  0.23  0.33  0.44
4       XOP  IEZ  ABC  0.62  0.20  0.18

我想遍历X_1至X_3列之间“ ABC”的每个实例的每个索引行。对于每个实例,我想从W_1到W_3列中提取相应的值,并将其附加到新的W列中。

例如,对于索引行1,如果X_3中出现ABC实例,它将从W_3中提取相应的值。

最终产品应如下所示。

Index   X_1  X_2  X_3  W_1   W_2    W_3     **W**
1       IEZ  XOP  ABC  0.42  0.18   0.40    **0.40**
2       PXJ  ABC  XES  0.47  0.12   0.41    **0.12**
3       ABC  RYE  PXE  0.23  0.33   0.44    **0.23**
4       XOP  IEZ  ABC  0.62  0.20   0.18    **0.18**

如何仅对导入的numpy和pandas模块执行此操作?

4 个答案:

答案 0 :(得分:0)

有趣。我相信有更好的方法,但是:

x_cols = [x for x in df.columns if x.startswith('X_')]
res_dfs = []
for col in x_cols:
    idx = col.split("_")[1]
    xw = df[col, "W_{idx}]
    xw = xw.loc[xw[col]  == 'ABC']
    xw = xw[[f"W_{idx}"]].rename(columns={f"W_{idx}": 'W'})
    res = df.join(xw).dropna()
    res_dfs.append(res)
df = pd.concat(res_dfs)

基本上,我遍历x col及其匹配的w col,找到x值是'abc'的位置,并用匹配的w值填充新的'w'列。

这是从我的手机上来的,所以我无法尝试,但这是一般的想法。

答案 1 :(得分:0)

import numpy as np
import pandas as pd

# df is your dataframe

# idxs = np.argwhere(df.values == "ABC") will also work
# if "ABC" only appears once per row.
idxs = np.argwhere(df.values[:, :3] == "ABC")
idxs[:, 1] += 3
w = df.values[idxs[:, 0], idxs[:, 1]]
df = df.assign(W=w)

matches = df.iloc[:, :3] == "ABC"
w = df.iloc[:, 3:].values[matches]
df = df.assign(W=w)

答案 2 :(得分:0)

另一种方法:

df = pd.DataFrame({'X_1' : ['IEZ', 'PXJ', 'ABC', 'XOP'],  
                   'X_2' : ['XOP', 'ABC', 'RYE', 'IEZ'], 
                   'X_3' : ['ABC', 'XES','PXE', 'ABC'],
                   'W_1' :  [0.42, 0.47, 0.23, 0.62],
                   'W_2' : [0.18, 0.12, 0.33, 0.20],
                   'W_3' :  [0.40, 0.41, 0.44, 0.18]})

首先,取数字列:

num_columns = df.loc[:,'W_1':'W_3']

接下来,使用X_1-> X_3列生成布尔掩码:

df_mask = (df.loc[:,'X_1':'X_3']=='ABC').values

最后,使用DataFrame mask方法,当单元格为True时将返回NaN,而当掩码为False时将返回单元格值。然后,我们将对结果行求和,并将其分配给原始DataFrame:

df['W'] = num_columns.mask(~df_mask).sum(axis=1)

当然可以将其合并为一行:

df['W'] = (df.loc[:,'W_1':'W_3']
            .mask(~(df.loc[:,'X_1':'X_3']=='ABC').values)
            .sum(axis=1))

编辑:

当然,这仅在每行只有'ABC'个实例的情况下才有效-您可能需要对此进行检查。

答案 3 :(得分:0)

pd.DataFrame.where与布尔索引一起使用:

df1, df2 = df[[c for c in df if c[0]=='X']], df[[c for c in df if c[0]=='W']]
df["W"] = df2.where((df1 == 'ABC').values).sum(1)
print(df)
   Index  X_1  X_2  X_3   W_1   W_2   W_3     W
0      1  IEZ  XOP  ABC  0.42  0.18  0.40  0.40
1      2  PXJ  ABC  XES  0.47  0.12  0.41  0.12
2      3  ABC  RYE  PXE  0.23  0.33  0.44  0.23
3      4  XOP  IEZ  ABC  0.62  0.20  0.18  0.18

这是基于df1df2始终具有相同形状的假设进行的。