pandas列出列之间常见的所有值

时间:2014-07-14 15:27:52

标签: python sql perl pandas dataframe

我有一个数据框,其中每列包含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中,我通过创建每列的数组和哈希来解决这个问题,然后针对每个哈希检查每个数组的每个元素,并使用每个比较后的print语句以及每个匹配,这样我的输出将如下所示:

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

但这会产生一个混乱的输出,它只是感觉它不是解决问题的最有效方法。当然,熊猫有这种做事的内置方式吗?

更新:我一直在努力学习使用SQL命令来完成此任务,但pandasql无法识别我的列名。所以基本上:

print pysqldf("SELECT * FROM df;")

打印表格,但是

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

打印"无"

我绝对不会在Pandas中使用SQL来解决这个问题。将欣赏有关如何列出显示在多个列中的所有ID值的任何和所有建议或建议

2 个答案:

答案 0 :(得分: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行的this answer。)

答案 1 :(得分: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