如何将几个类似的.csv文件组合成一个给定结构的数据帧

时间:2013-10-08 11:43:17

标签: python r csv dataframe

我有许多结构相似的.csv文件:

1.csv

Type n
A   1
B   20
C   34
D   5
...

2.csv

Type n
A   2
B   15
C   16
D   5
...

我希望将它们组合在一起:

Type  n1   n2
  A   1    2
  B   20   15
  C   34   16
  D   5    5
  ...

当我使用lapply时,我得到了

 Type n  Type   n
  A   1    A    2
  B   20   B    15
  C   34   C    16
  D   5    D    5
  ...

有没有简单的方法将它们正确组合?

我愿意接受R或Python的解决方案

3 个答案:

答案 0 :(得分:3)

解释1:每个CSV的相同数据结构

如果结构相同,请考虑以下两个选项,但首先是一些示例数据:

cat("Type n", "A  1", "B  20", "C  34", "D  5", sep = "\n", file = "myfile1.txt")
cat("Type n", "A  2", "B  15", "C  16", "D  5", sep = "\n", file = "myfile2.txt")

选项1:当您使用"NULL"(带引号)作为需要删除的列的colClasses来读取数据时,删除第一列。使用cbind将文件放在一起。

x <- read.table("myfile1.txt", header=TRUE)
y <- read.table("myfile2.txt", header=TRUE, colClasses=c("NULL", "numeric"))
cbind(x, y)
#   Type  n  n
# 1    A  1  2
# 2    B 20 15
# 3    C 34 16
# 4    D  5  5

## For more files:
## do.call(cbind, list(x, y, ...))

选项2:正常读取文件,然后使用c(FALSE, TRUE)向量进行子集化,将所有对象的第一列放在listcbind中。< / p>

x1 <- read.table("myfile1.txt", header = TRUE)
y1 <- read.table("myfile2.txt", header = TRUE)

fileList <- list(x1, y1)
cbind(x1[1], do.call(cbind, fileList)[c(FALSE, TRUE)])
#   Type  n n.1
# 1    A  1   2
# 2    B 20  15
# 3    C 34  16
# 4    D  5   5

当然,以上只是极少数的例子。我假设你每个文件中实际上有两列以上。使用实际匹配列的TRUEFALSE的向量来分别保留和删除第二个选项,并使用"NULL"和第一个选项的对象类。


解释2:每个CSV的类似数据结构

如果数据结构类似相同,则可能需要使用merge。请考虑以下示例数据。前三个文件具有相同的结构,但第四个文件"myfile4.txt"具有A,B,D和E作为“类型”值,而其他三个具有“A”,“B”,“C” “和”D“

cat("Type n", "A  1", "B  20", "C  34", "D  5", sep = "\n", file = "myfile1.txt")
cat("Type n", "A  2", "B  15", "C  16", "D  5", sep = "\n", file = "myfile2.txt")
cat("Type n", "A  1", "B   5", "C   6", "D  7", sep = "\n", file = "myfile3.txt")
cat("Type n", "A  8", "B   9", "D  11", "E  0", sep = "\n", file = "myfile4.txt")

以下是我们如何解决这个问题。

  1. 批量阅读文件:

    x <- list.files(pattern="myfile")
    y <- lapply(x, read.table, header = TRUE)
    
  2. 如果多个merge无法创建唯一名称,则可能会导致错误。通过为非id列创建唯一名称来帮助merge

    library(data.table) ## for `setnames`
    ## setnames will silently assign new names 
    ##   to the original data in list "y"
    invisible(lapply(seq_along(y), function(z) 
      setnames(y[[z]], "n", paste("n", z, sep = "_"))))
    
  3. 使用“{1}}将Reduce列在一起,使用”类型“列作为”ID“。

    merge

答案 1 :(得分:1)

在Python中

,您应该使用pandas来执行这些操作:

import pandas as pd

df1 = pd.read_csv('1.csv', sep='\s+', index_col=0)
df2 = pd.read_csv('2.csv', sep='\s+', index_col=0)

pd.concat([df1, df2], axis=1)
Out[16]: 
       n   n
Type        
A      1   2
B     20  15
C     34  16
D      5   5

如果您希望更多自动列重命名:

pd.merge(df1, df2, left_index=True, right_index=True, suffixes=['1', '2'])
Out[20]: 
      n1  n2
Type        
A      1   2
B     20  15
C     34  16
D      5   5

答案 2 :(得分:0)

此处的另一个解决方案是假设不需要合并。例如,如果您有三个文件,则可以按如下方式阅读:

n <- 1:3
x <- lapply(sprintf('%s.csv', n), read.csv)

您只想删除每个表中的第一列,这样您就可以使用sapply()上的[[.data.frame删除不需要的列,然后将其全部合并到一个数据框中。

data.frame(Type = x[[1]]$Type, sapply(x, '[[', -1))

或者如果你真的想要n1n2等形式的名字:

data.frame(
  Type = x[[1]]$Type, 
  setNames(lapply(x, '[[', -1), paste0('n', n))
)