Python 数据帧中的成对矩阵

Python 数据帧中的成对矩阵,python,pandas,Python,Pandas,我有一个熊猫数据框,看起来像这样: Al01 BBR60 CA07 NL219 AAEAMEVAT MP南部MP 南安 AAGAAVKGV NP NaN NP Adrglrdi NaN NP NaN NaN AEIMKICST PB1 NaN NaN PB1 阿夫德拉格南NP 阿夫德拉格纳南 大约有一千行和半打列。大多数单元格为空(NaN)。我想知道每一列中出现文本的概率是多少,因为不同的列中都有文本。例如,此处的小片段将生成如下内容: Al01 BBR60 CA07 NL219 Al01

我有一个熊猫数据框,看起来像这样:

Al01 BBR60 CA07 NL219 AAEAMEVAT MP南部MP 南安 AAGAAVKGV NP NaN NP Adrglrdi NaN NP NaN NaN AEIMKICST PB1 NaN NaN PB1 阿夫德拉格南NP 阿夫德拉格纳南

大约有一千行和半打列。大多数单元格为空(NaN)。我想知道每一列中出现文本的概率是多少,因为不同的列中都有文本。例如,此处的小片段将生成如下内容:

Al01 BBR60 CA07 NL219 Al01 4 0 2 3 BBR60 0 1 0 0 CA07 2 0 3 3 NL2193034

也就是说,在Al01列中有4个点击;在这4个点击中,没有一个是BBR60列中的点击,2个也是CA07列中的点击,3个是NL219列中的点击。等等


我可以一步一步地浏览每一列,然后用这些值构建一个dict,但这看起来很笨拙。有更简单的方法吗?

您正在执行的操作可以表示为的应用程序--它是每对列之间的内积:

Al01 BBR60 CA07 NL219 AAEAMEVAT MP NaN MP MP AAFEDLRLL NaN NaN NaN NaN AAGAAVKGV NP NaN NP NP ADRGLLRDI NaN NP NaN NaN AEIMKICST PB1 NaN NaN PB1 AFDERRAGK NaN NaN NP NP AFDERRAGK NP NaN NaN NaN 屈服

Al01 BBR60 CA07 NL219 Al01 4 0 2 3 BBR60 0 1 0 0 CA07 2 0 3 3 NL219 3 0 3 4
通常,当计算归结为独立于索引的数值运算时,使用NumPy比使用Pandas更快。这里的情况似乎就是这样:

import numpy as np
import pandas as pd

df = pd.read_table('data', sep='\s+')
print(df)
#   Al01 BBR60 CA07 NL219
# 0   MP   NaN   MP    MP
# 1  NaN   NaN  NaN   NaN
# 2   NP   NaN   NP    NP
# 3  NaN    NP  NaN   NaN
# 4  PB1   NaN  NaN   PB1
# 5  NaN   NaN   NP    NP
# 6   NP   NaN  NaN   NaN

arr = (~df.isnull()).values.astype('int')
print(arr)
# [[1 0 1 1]
#  [0 0 0 0]
#  [1 0 1 1]
#  [0 1 0 0]
#  [1 0 0 1]
#  [0 0 1 1]
#  [1 0 0 0]]

result = pd.DataFrame(np.einsum('ij,ik', arr, arr),
                      columns=df.columns, index=df.columns)
print(result)

它只是矩阵乘法:

       Al01  BBR60  CA07  NL219
Al01      4      0     2      3
BBR60     0      1     0      0
CA07      2      0     3      3
NL219     3      0     3      4
输出:

In [130]: %timeit df2 = df.applymap(lambda x: int(not pd.isnull(x)));  df2.T.dot(df2)
1000 loops, best of 3: 1.12 ms per loop

In [132]: %timeit arr = (~df.isnull()).values.astype('int'); pd.DataFrame(np.einsum('ij,ik', arr, arr), columns=df.columns, index=df.columns)
10000 loops, best of 3: 132 µs per loop
import pandas as pd
df = pd.read_csv('data.csv',index_col=0, delim_whitespace=True)
df2 = df.applymap(lambda x: int(not pd.isnull(x)))
print df2.T.dot(df2)
           Al01  BBR60  CA07  NL219
Al01      4      0     2      3
BBR60     0      1     0      0
CA07      2      0     3      3
NL219     3      0     3      4

[4 rows x 4 columns]