如何返回与熊猫数据框中的每一行都符合条件的列标题?

时间:2020-06-01 07:33:46

标签: python pandas numpy

我的熊猫数据框 df 的格式为:

     Col1      Col2      Col3      Col4

0    True      False     True      False
1    False     False     False     False
2    False     True      False     False
3    True      True      True      True

True和False是布尔值。

我正在尝试生成一个新的熊猫数据框 new_df ,其外观应为:

     Matched_Cols

0    [Col1, Col3]
1    []
2    [Col2]
3    [Col1, Col2, Col3, Col4]

最有效的方法是什么?

4 个答案:

答案 0 :(得分:4)

方法1

这里涉及数组数据处理-

def iter_accum(df):
    c = df.columns.values.astype(str)
    return pd.DataFrame({'Matched_Cols':[c[i] for i in df.values]})

样本输出-

In [41]: df
Out[41]: 
    Col1   Col2   Col3   Col4
0   True  False   True  False
1  False  False  False  False
2  False   True  False  False
3   True   True   True   True

In [42]: iter_accum(df)
Out[42]: 
               Matched_Cols
0              [Col1, Col3]
1                        []
2                    [Col2]
3  [Col1, Col2, Col3, Col4]

方法2

另一个切片数据和一些布尔索引-

def slice_accum(df):
    c = df.columns.values.astype(str)
    a = df.values
    vals = np.broadcast_to(c,a.shape)[a]
    I = np.r_[0,a.sum(1).cumsum()]
    ac = []
    for (i,j) in zip(I[:-1],I[1:]):
        ac.append(vals[i:j])
    return pd.DataFrame({'Matched_Cols':ac})

基准化

其他建议的解决方案-

# @jezrael's soln-1
def jez1(df):
    return df.apply(lambda x: x.index[x].tolist(), axis=1)

# @jezrael's soln-2
def jez2(df):
    return df.dot(df.columns + ',').str.rstrip(',').str.split(',')

# @Shubham Sharma's soln
def Shubham1(df):
    return df.agg(lambda s: s.index[s].values, axis=1) 

# @sammywemmy's soln
def sammywemmy1(df):
    return pd.DataFrame({'Matched_Cols':[np.compress(x,y) for x,y in zip(df.to_numpy(),np.tile(df.columns,(len(df),1)))]})

使用benchit程序包(打包在一起的基准测试工具很少;免责声明:我是它的作者)对建议的解决方案进行基准测试。

import benchit
funcs = [iter_accum,slice_accum,jez1,jez2,Shubham1,sammywemmy1]
in_ = {n:pd.DataFrame(np.random.rand(n,n)>0.5, columns=['Col'+str(i) for i in range(1,n+1)]) for n in [4,20,100,200,500,1000]}
t = benchit.timings(funcs, in_, input_name='Len')
t.rank()
t.plot(logx=True)

enter image description here

答案 1 :(得分:2)

您可以为每行索引值过滤原始DataFrame中的列名是什么,然后转换为列表:

df['Matched_Cols'] = df.apply(lambda x: x.index[x].tolist(), axis=1)

或使用DataFrame.dot与带有分隔符的列名称进行矩阵乘法,用Series.str.rstrip删除最后一个分隔符值,最后使用Series.str.split

df['Matched_Cols'] = df.dot(df.columns + ',').str.rstrip(',').str.split(',')

print (df)
    Col1   Col2   Col3   Col4              Matched_Cols
0   True  False   True  False              [Col1, Col3]
1  False  False  False  False                        []
2  False   True  False  False                    [Col2]
3   True   True   True   True  [Col1, Col2, Col3, Col4]

答案 2 :(得分:1)

不必要的长:

    [INFO] *** No cache found for userprofile, building with all downstream dependencies
   [INFO] *** Building scheme "CloudSdk" in CloudSdk.xcworkspace
    [INFO] Build Failed
    [INFO] 	Task failed with exit code 65:
       
 [INFO] 	/usr/bin/xcrun xcodebuild -workspace /Users/rsun0002/Documents/Integ/Project/ProjectFolder/Carthage/Checkouts/sharesdk_ios/CloudSdk.xcworkspace -scheme CloudShareSdk -configuration Release -derivedDataPath 

/Users/username/Library/Caches/org.carthage.CarthageKit/DerivedData/11.2.1_11B500/sharesdk_ios/1.0.7 -sdk iphoneos ONLY_ACTIVE_ARCH=NO CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY= CARTHAGE=YES archive -archivePath /var/folders/zk/vqylrdq57njcx51zcwptgj41ybfztg/T/sharesdk_ios SKIP_INSTALL=YES GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=NO 

CLANG_ENABLE_CODE_COVERAGE=NO STRIP_INSTALLED_PRODUCT=NO (launched in /Users/username/Documents/Integ/Project/ProjectFolder/Carthage/Checkouts/sharesdk_ios)

答案 3 :(得分:1)

使用:

df['Matched_Cols'] = df.agg(lambda s: s.index[s].values, axis=1) 

结果:

   Col1   Col2   Col3   Col4               Matched_Cols

0   True  False   True  False              [Col1, Col3]
1  False  False  False  False                        []
2  False   True  False  False                    [Col2]
3   True   True   True   True  [Col1, Col2, Col3, Col4]