pandas列出两列之间的所有共同值

1 投票
2 回答
912 浏览
提问于 2025-04-18 13:16

我有一个数据表,每一列都包含一些ID号码,长得像这样:

LC3B.low    LC3B.hi  P62.low    P62.hi
PT 65       PT 172   PT 86      PT 135
PT 86       PT 65    PT 38      PT 56
PT 251      PT 251   PT 217     PT 261

我想列出那些在两个或更多列中出现的ID。所以根据我提供的值,pandas会显示:

  • LC3B.low和LC3B.hi共享“PT 65”和“PT 251”
  • LC3B.low和P62.low共享“PT 86”

我刚开始接触Pandas,以前用的是Perl。在Perl中,我会通过创建每一列的数组和哈希表来解决这个问题,然后检查每个数组中的每个元素和每个哈希表的元素,比较时会用打印语句显示每次比较和匹配的结果,这样我的输出会像这样:

LC3B.low vs LC3B.hi
PT 65
PT 251
LC3B.low vs P62.low
PT 86
LC3B.low vs P62.hi
LC3B.hi vs P62.low
LC3B.hi vs P62.hi
P62.low vs P62.hi

但这样输出的结果很乱,感觉也不是解决问题的最有效方法。难道Pandas没有内置的方式来处理这种情况吗?

更新:我一直在尝试用SQL命令来完成这个任务,但pandasql不识别我的列名。所以基本上:

print pysqldf("SELECT * FROM df;")

可以打印出表格,但,

print pysqldf("SELECT ATG12.low FROM df;")

却打印出“None”

我并不一定要在Pandas中使用SQL来解决这个问题。任何建议或意见都非常感谢,特别是如何列出所有在多个列中出现的ID值。

2 个回答

0

这里有一个解决方案,希望在处理大数据集时能运行得更快,因为它没有使用for循环:

import pandas as pd
dfData = pd.DataFrame({'LC3B.low':['PT 65','PT 86','PT 251'],'LC3B.hi':['PT 172','PT 65','PT 251'], 'P62.low':['PT 86','PT 38','PT 217'], 'P62.hi':['PT 135','PT 56','PT 261']})          

x =  dfData.stack().reset_index()
x.columns = ['A','Col','Val']
y = x.drop(['A'],axis = 1)

valCount = y.groupby(['Val']).count()
valCount.columns = ['ColumnCount']

mergedData = pd.merge(y,valCount, left_on ='Val', right_index=True) 

output_data = mergedData[mergedData['ColumnCount'] >1].drop(['ColumnCount'],axis = 1)

print output_data

    Col     Val
1  LC3B.low   PT 65
4   LC3B.hi   PT 65
3   P62.low   PT 86
5  LC3B.low   PT 86
8   LC3B.hi  PT 251
9  LC3B.low  PT 251
0

这个方法看起来有点复杂,但它会输出一个数据表,让你能找到你想要的所有信息。

在这个 results_df 表格中,每一行都显示了原始数据表中某一列的行索引出现的频率。

import pandas as pd
df = pd.DataFrame({'A': [1,2,3],
                   'B': [3,4,5],
                   'C': [1,4,8],
                   'D': [3,7,2]})
unique_vals = pd.Series(df.values.ravel()).unique()
data_dict = {}
for i in unique_vals:
    row = []
    for v in df.columns:
        row.append( (df[v]==i).sum())
    data_dict[i] = row

results_df = pd.DataFrame(data_dict).T
results_df.columns = df.columns

results_df

   A  B  C  D
1  1  0  1  0
2  1  0  0  1
3  1  1  0  1
4  0  1  1  0
5  0  1  0  0
7  0  0  0  1
8  0  0  1  0

(感谢 这个回答提供的 unique_vals 代码行。)

撰写回答