提问者:小点点

熊猫将True列转换为列值


我有以下布尔值表:

pd.DataFrame(data={'val1': [True, False, False, True], 
                   'val2': [False, True, False, True], 
                   'val3': [True, True, False, True], 
                   'val4': [True, False, True, False], 
                   'val5': [True, True, False, False],
                   'val6': [False, False, True, True]},
                   index=pd.Series([1, 2, 3, 4], name='index'))

我想创建一个具有相同索引的新数据帧,但每行都有前一列的前三个 True 列名。

如果一行少于三个真值,则新数据帧将具有空值。


共2个答案

匿名用户

尝试使用,然后拆分

#df = df.set_index('index')
out = df.dot(df.columns + ',').str[:-1].str.split(',',expand=True).iloc[:,:3]
out
Out[258]: 
          0     1     2
index                  
1      val1  val3  val4
2      val2  val3  val5
3      val4  val6  None
4      val1  val2  val3

匿名用户

您可以使用numpyargsort来执行此操作,以根据True值的位置对列进行切片。

然后使用whereNaNFalse的行,以防True值太少。

import numpy as np
import pandas as pd

# Get the first `N` True columns.
N = 3

arr = df.to_numpy()
data = df.columns.to_numpy()[(~arr).argsort(axis=1, kind='stable')[:, :N]]
mask = np.ones_like(data).cumsum(1) <= arr.sum(1)[:, None]

res = pd.DataFrame(data, columns=[f'TrueVal{i+1}' for i in range(N)],
                   index=df.index).where(mask)
print(res)

      TrueVal1 TrueVal2 TrueVal3
index                           
1         val1     val3     val4
2         val2     val3     val5
3         val4     val6      NaN
4         val1     val2     val3