熊猫用nan计算2列的不同组合

A11*_*122 4 python dataframe pandas

我有一个类似于的数据框

df = pd.DataFrame({'A': [1, np.nan,2,3, np.nan,4], 'B': [np.nan, 1,np.nan,2, 3, np.nan]})
df
     A    B
0  1.0  NaN
1  NaN  1.0
2  2.0  NaN
3  3.0  2.0
4  NaN  3.0
5  4.0  NaN
Run Code Online (Sandbox Code Playgroud)

如何计算A是np.nan但B不是np.nan,A不是np.nanB np.nan且A和B都不是的出现次数np.nan

我试过了,df.groupby(['A', 'B']).count()但没有读到的行np.nan

cs9*_*s95 6

如果仅处理两列,则有一个非常简单的解决方案,其中涉及为列A和B分配简单的权重,然后对其求和。

v = df.isna().mul([1, 2]).sum(1).value_counts() 
v.index = v.index.map({2: 'only B', 1: 'only A', 0: 'neither'})    
v

only B     3
only A     2
neither    1
dtype: int64
Run Code Online (Sandbox Code Playgroud)

另一种替代方法与pivot_tablestack可以通过以下方式实现,

df.isna().pivot_table(index='A', columns='B', aggfunc='size').stack()

A      B    
False  False    1.0
       True     3.0
True   False    2.0
dtype: float64
Run Code Online (Sandbox Code Playgroud)


WeN*_*Ben 6

使用

df.isnull().groupby(['A','B']).size()
Out[541]: 
A      B    
False  False    1
       True     3
True   False    2
dtype: int64
Run Code Online (Sandbox Code Playgroud)


jez*_*ael 5

您可以将DataFrame.isnawith crosstab用于计数True值:

df1 = df.isna()
df2 = pd.crosstab(df1.A, df1.B)
print (df2)
B      False  True 
A                  
False      1      3
True       2      0
Run Code Online (Sandbox Code Playgroud)

对于标量:

print (df2.loc[False, False])
1
Run Code Online (Sandbox Code Playgroud)
df2 = pd.crosstab(df1.A, df1.B).add_prefix('B_').rename(lambda x: 'A_' + str(x))
print (df2)
B        B_False  B_True
A                       
A_False        1       3
A_True         2       0
Run Code Online (Sandbox Code Playgroud)

然后对于标量使用索引:

print (df2.loc['A_False', 'B_False'])
1
Run Code Online (Sandbox Code Playgroud)

另一种解决方案是DataFrame.dot按列名称使用Series.replaceSeries.value_counts

df = pd.DataFrame({'A': [1, np.nan,2,3, np.nan,4, np.nan], 
                   'B': [np.nan, 1,np.nan,2, 3, np.nan, np.nan]})

s = df.isna().dot(df.columns).replace({'':'no match'}).value_counts()
print (s)

B           3
A           2
no match    1
AB          1
dtype: int64
Run Code Online (Sandbox Code Playgroud)