如何使用另一个 DataFrame 的值作为索引和列引用(并替换其他值)来保留 DataFrame 中的值?

Rom*_*_91 5 python replace dataframe pandas

我有以下两个数据框:

import pandas as pd

df = pd.DataFrame([[0, 0, 0, 0, 0],
                   [0, 0, 0, 0, 0],
                   [0, 0, 0, 0, 0],
                   [0, 0, 0, 0, 0],
                   [0, 0, 0, 0, 0]],
                  index = [0, 0.25, 0.50, 0.75, 1],
                  columns = [0, 0.25, 0.50, 0.75, 1])

df_cross = pd.DataFrame([[0.0, 0.25],
                         [0.0, 0.75],
                         [0.5, 1]],
                        columns = ['indexes_to_keep',
                                   'cols_to_keep'])
Run Code Online (Sandbox Code Playgroud)

df:

      0.00  0.25  0.50  0.75  1.00
0.00     0     0     0     0     0
0.25     0     0     0     0     0
0.50     0     0     0     0     0
0.75     0     0     0     0     0
1.00     0     0     0     0     0
Run Code Online (Sandbox Code Playgroud)

df_cross:

   indexes_to_keep  cols_to_keep
0              0.0          0.25
1              0.0          0.75
2              0.5          1.00
Run Code Online (Sandbox Code Playgroud)

df我有我的存储数据,并且 df_cross 包含我想要保留值的索引和列。df索引和列与我想用字符串替换的任何行都不匹配的值df_cross(例如“NaN”)。

预期输出是:

     0.00 0.25 0.50 0.75 1.00
0.00  NaN    0  NaN    0  NaN
0.25  NaN  NaN  NaN  NaN  NaN
0.50  NaN  NaN  NaN  NaN    0
0.75  NaN  NaN  NaN  NaN  NaN
1.00  NaN  NaN  NaN  NaN  NaN
Run Code Online (Sandbox Code Playgroud)

提前致谢。

Qua*_*ang 6

Pandas 不支持使用坐标数组设置元素。您需要使用 numpy:

# integer locs
rows = df.index.get_indexer(df_cross.indexes_to_keep)
cols = df.columns.get_indexer(df_cross.cols_to_keep)

# where we want to keep the data
mask = np.full(df.shape, False)
mask[rows, cols] = True

df[:] = df.where(mask)
Run Code Online (Sandbox Code Playgroud)

另一种仅使用 Pandas 创建的方法mask是:

mask = (df_cross.assign(val=True)
          .set_index(['indexes_to_keep', 'cols_to_keep'])
          ['val'].unstack(fill_value=False)
       )
Run Code Online (Sandbox Code Playgroud)

输出:

      0.00  0.25  0.50  0.75  1.00
0.00   NaN   0.0   NaN   0.0   NaN
0.25   NaN   NaN   NaN   NaN   NaN
0.50   NaN   NaN   NaN   NaN   0.0
0.75   NaN   NaN   NaN   NaN   NaN
1.00   NaN   NaN   NaN   NaN   NaN
Run Code Online (Sandbox Code Playgroud)


Shu*_*rma 5

让我们尝试crosstab一下df_cross,然后用它where来掩盖值

s = pd.crosstab(*df_cross.values.T)
df.where(s == 1)
Run Code Online (Sandbox Code Playgroud)
      0.00  0.25  0.50  0.75  1.00
0.00   NaN   0.0   NaN   0.0   NaN
0.25   NaN   NaN   NaN   NaN   NaN
0.50   NaN   NaN   NaN   NaN   0.0
0.75   NaN   NaN   NaN   NaN   NaN
1.00   NaN   NaN   NaN   NaN   NaN
Run Code Online (Sandbox Code Playgroud)

PS:pd.crosstab(*df_cross.values.T)只是一个语法快捷方式,实际上等同于使用pd.crosstab(df.indexes_to_keep, df.cols_to_keep)