Pandas 将 True 列转换为列值
Posted
技术标签:
【中文标题】Pandas 将 True 列转换为列值【英文标题】:Pandas turn True columns into column value 【发布时间】:2021-10-13 10:07:34 【问题描述】:我有下表的布尔值:
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'))
index | val1 | val2 | val3 | val4 | val5 | val6 |
---|---|---|---|---|---|---|
1 | True | False | True | True | True | False |
2 | False | True | True | False | True | False |
3 | False | False | False | True | False | True |
4 | True | True | True | False | False | True |
我想创建一个具有相同索引的新数据框,但每一行都有前一列的前三个 True 列名。
index | TrueVal1 | TrueVal2 | TrueVal3 |
---|---|---|---|
1 | val1 | val3 | val4 |
2 | val2 | val3 | val5 |
3 | val4 | val6 | NaN |
4 | val1 | val2 | val3 |
如果一行的 True 值少于三个,则新数据框的值为 Null。
【问题讨论】:
【参考方案1】:尝试使用 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】:您可以使用numpy
+ argsort
执行此操作,以按True
值的位置对列进行切片。
然后使用 where
到 NaN
的行 False
以防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'TrueVali+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
【讨论】:
以上是关于Pandas 将 True 列转换为列值的主要内容,如果未能解决你的问题,请参考以下文章