【问题标题】:Column-wise diff of two CSV files两个 CSV 文件的列差异
【发布时间】:2015-02-13 00:57:22
【问题描述】:

我正在尝试比较两个 CSV 文件(下面还有更多类似的文件)。我尝试了很多方法,使用列表、dictreader 等等,但没有给我所需的输出。我想比较所有具有相同 !Sample_title 和 !Sample_geo_accession 值的行(其位置不同)。我已经为此苦苦挣扎了三天,无法找到解决方案。我非常感谢任何帮助。

CSV1:

!Sample_title,!Sample_geo_accession,!Sample_status,!Sample_type,!Sample_source_name_ch1
body,GSM501443,Public on july 22 2010,ribonucleic acid,FB_50_12wk
foreign,GSM501445,Public on july 22 2010,ribonucleic acid,FB_0_12wk
HJCENV,GSM501446,Public on july 22 2010,ribonucleic acid,FB_50_12wk
AsDW,GSM501444,Public on july 22 2010,ribonucleic acid,FB_0_12wk

CSV2:

!Sample_title,!Sample_type,!Sample_source_name_ch1,!Sample_geo_accession
AsDW,ribonucleic acid,FB_0,GSM501444
foreign,ribonucleic acid,FB,GSM501449
HJCENV,RNA,12wk,GSM501446

所需的输出(相对于 CSV2):

添加:

{!Sample_status:{HJCENV:Public on july 22 2010,AsDW:Public on july 22 2010}} #Added columns, not rows.

已删除:

{} #Since nothing's deleted with respect to CSV2

改变:

{!Sample_title:AsDW,!Sample_source_name_ch1:(FB_0_12wk,FB_0),!Sample_geo_accession:GSM501444
!Sample_title:HJCENV,!Sample_type:(ribonucleic acid,RNA),!Sample_source_name_ch1:(FB_50_12wk,12wk),!Sample_geo_accession:GSM501446}
#foreign,ribonucleic acid,FB,GSM501449 doesn't come here since the !Sample_geo_accession column values didn't match. 

编辑:

这里 添加的字典应为在 CSV1 中找到的每个 !Sample_title(当 !Sample_title 和 !Sample_geo_accession 在 CSV1 和 CSV2 中匹配时)提供任何附加列及其值(如果它的列数比 CSV2 多)

Deleted 字典的作用与Added 相似,只是它查找已删除的列。

Changed 给出了文件及其标题中不同的值。

所以基本上它应该比较苹果和苹果(当标题名称匹配时),而不是苹果和橙子(按列位置)

【问题讨论】:

  • 您可以使用index 连续查找您要查找的职位吗?
  • 按索引,如果你的意思是硬编码列号,不,因为它们可能会因文件而异。 @kiran.koduru
  • 请注意字典键必须是唯一的。除非您运行迭代进行更新,否则您将无法在同一字典中重用 !Sample_title!Sample_source_name_chi1。而且,这是使用 Python 的 Pandas 模块的好案例。您可以将两个 csv 文件作为数据框导入,通过 !Sample_title 合并输出、聚合、透视相应的列。
  • @abn:如果您没有得到答案,请注意并解决任何澄清请求;根据需要多次编辑您的问题以改进它。永远不要多次问同一个问题;这是一种违规行为,它会降低 SO,人们会(正确地)避开你。

标签: python csv dictionary compare


【解决方案1】:

您的问题的定义仍然很糟糕。首先,我们必须解码问题。 您说“区分两个 CSV 文件”,这通常意味着按行区分,可能首先按索引列按行重新排序 ['!Sample_title','!Sample_geo_accession']

但您实际上想要按列 差异。具体来说,您想知道在 csv2 中添加了哪些列,删除了哪些列,以及对于公共列,哪些条目(行)在 csv2 中发生了更改。 现在,您希望这些差异按单个系列计算和呈现,还是同时跨所有列计算和呈现?

类似于以下内容:

import pandas as pd
pd.options.display.width = 200

df1 = pd.read_csv('1.csv', index_col=['!Sample_title','!Sample_geo_accession'])
df2 = pd.read_csv('2.csv', index_col=['!Sample_title','!Sample_geo_accession'])

cols_common  = (df1.columns & df2.columns).tolist()
cols_added   = (df2.columns - df1.columns).tolist()
cols_deleted = (df1.columns - df2.columns).tolist()

print "\nAdded",   df2.ix[:, cols_added]
print "\nDeleted", df1.ix[:, cols_deleted]
print "\nChanged", df2.ix[:, cols_common]

输出:

Added:
[(AsDW, GSM501444), (foreign, GSM501449), (HJCENV, GSM501446)]

Deleted                                              !Sample_status
!Sample_title !Sample_geo_accession                        
body          GSM501443              Public on july 22 2010
foreign       GSM501445              Public on july 22 2010
HJCENV        GSM501446              Public on july 22 2010
AsDW          GSM501444              Public on july 22 2010

Changed                                          !Sample_type !Sample_source_name_ch1
!Sample_title !Sample_geo_accession                                          
AsDW          GSM501444              ribonucleic acid                    FB_0
foreign       GSM501449              ribonucleic acid                      FB
HJCENV        GSM501446                           RNA                    12wk

您似乎还需要我们对列重新排序,以便 df1、df2 的顺序相同。 但是你没有告诉我们应该如何比较 '!Sample_source_name_ch1',因为 'FB_0_12wk' != '12wk'。

在你明确你的要求之前,我不会再做这个了。

【讨论】:

  • 谢谢。抱歉走了。我不想重新排序行,因为行数本身是不同的。我认为 'FB_0_12wk' != '12wk' 很明显,所以它应该属于已更改的类别。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-11
相关资源
最近更新 更多