pandas列出两列之间的所有共同值
我有一个数据表,每一列都包含一些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
代码行。)