Pandas将True列转换为列值。

3

我有以下布尔值表:

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'))
索引 值1 值2 值3 值4 值5 值6
1
2
3
4

我想创建一个新的数据框(dataframe),该数据框具有相同的索引,但每行都包含来自上一列的前三个True列名。

索引 True值1 True值2 True值3
1 值1 值3 值4
2 值2 值3 值5
3 值4 值6 NaN
4 值1 值2 值3

如果某行的True值少于三个,新数据框将具有Null值。

2个回答

3
尝试使用点(dot),然后使用分割(split)
#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

2
你可以使用 numpyargsort 来通过 True 值的位置来切分列。

然后使用 where 来将那些太少 True 值的行变为 NaN
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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接