【问题标题】:How to create one dataframe from multiple csv files in a folder如何从文件夹中的多个 csv 文件创建一个数据框
【发布时间】:2018-05-09 14:45:27
【问题描述】:

我在一个文件夹中有一个 CSV 文件列表(A1.csv、A2.csv........D10.csv),其中包含两列但多行的数据。基本上,我想从所有 csv 文件中提取最后一行和第二列的值 See the picture to understand better

并创建一个数据框,该数据框将在第一列中包含文件名,在第二列中包含提取的值(C)。

现在,我可以通过创建另一个 CSV 文件列表并稍后将它们连接到一个数据框中来实现。

是否可以将 CSV 文件生成的每个数据帧存储到一个列表中,然后将它们连接起来(rbind 在 R 中所做的)。我在 R 中尝试了这段代码,它可以工作。但我想学习 R 或 python 中更有效的方法。(最好是 Python,因为我正在尝试学习 python)

#read through csv files and select the last row 2nd column
m=c(NULL)
aa=c(NULL)
f=list.files(path = getwd(),pattern = '.*csv')
for (g in f){
aa=read.csv(g)
m=tail(aa,1)
q=m[,2]
yy=data.frame(ID=g,Final=q)
write.csv(yy,file = paste("Filename/",g),row.names = F)
}
###concatanate into one file
readFile=list.files(path = getwd(),pattern = "*.csv")
Alldata=lapply(readFile,function(filename){
dummy=read.csv(filename)
return(dummy)
})
FinalFIle=do.call(rbind,Alldata)
write.csv(FinalFIle,file = "FinalFIle.csv",row.names = F)

【问题讨论】:

  • 到目前为止尝试了什么?请发布您的代码。
  • 现在你可以在帖子中看到我的代码

标签: python r dataframe concatenation


【解决方案1】:

这是在 R 中使用 tidyverse 的另一个选项:

library(tidyverse)

# In my example, I'm using a folder with 4 Chicago Crime Datasets
setwd("INSERT/PATH/HERE")

files <- list.files()

tibble(files) %>%
  mutate(file_contents = map(files, ~ read_csv(file.path(.), n_max = 10))) %>% 
  unnest(file_contents) %>%
  group_by(files) %>%
  slice(n()) %>% 
  select(1:2)

返回:

# A tibble: 4 x 2
# Groups:   filename [4]
                         filename    X1
                            <chr> <int>
1 Chicago_Crimes_2001_to_2004.csv  4904
2 Chicago_Crimes_2005_to_2007.csv    10
3 Chicago_Crimes_2008_to_2011.csv  5867
4 Chicago_Crimes_2012_to_2017.csv  1891

请注意,不需要 n_max = 10 参数。我只包含这个是因为我使用的文件非常大。

任何有兴趣的人,可以在here找到数据集。

此外,您可能希望避免使用setwd() 设置工作目录。如果是这种情况,您可以在list.files() 中使用附加参数full.names = TRUE

path <- "INSERT/PATH/HERE"
files <- list.files(path, full.names = TRUE)

我推荐这种方法,因为包含 setwd() 行的脚本不灵活,路径会因用户而异。

【讨论】:

    【解决方案2】:

    Python 解决方案

    >>> import pandas as pd
    >>> files = ['A1.csv', 'A2.csv', ... , 'D10.csv']
    >>> df_final = pd.Dataframe({fname: pd.read_csv(fname).iat[-1, 1] for fname in files})
    

    【讨论】:

      【解决方案3】:

      对于bash 和朋友来说,这是一个简单的案例。这个单线

      for i in A*.csv B*.csv C*.csv D*.csv; do awk -F , 'END{ print $NF }' "$i"; done
      

      提取符合您给定模式的任意数量文件的右下角字段,无论有多少行或列。如果所有文件都在一个文件夹中,并且它们是该文件夹中唯一的 .csv 文件,并且您想将结果保存在一个新文件中,则可以这样做:

      for i in *.csv; do awk -F , 'END{ print $NF }' "$i"; done > extract.txt
      

      【讨论】:

        【解决方案4】:

        这是 R 中的一个选项。

        第 1 步:准备一个带有文件名的向量。如果文件夹中的文件太多,list.files 函数可能会很有用。在这里,我只是手动创建了它。我还假设所有文件都存储在工作目录中。否则,您将需要构建文件路径。

        file_vec <- c("A1.csv", "A2.csv", "A3.csv")
        

        第 2 步:根据 file_vec 读取所有 CSV 文件。关键是使用lapply函数对file_vec中的每个元素应用read.csv

        dt_list <- lapply(file_vec, read.csv, stringsAsFactors = FALSE)
        

        第 3 步:准备一个向量,显示不带 .csv 的文件名

        name_vec <- sub(".csv", "", file_vec)
        

        第 4 步:创建数据框。 x[nrow(x), 2] 是一种访问第二列最后一个值的方法。

        dt_final <- data.frame(File = name_vec,
                               Value = sapply(dt_list, function(x) x[nrow(x), 2]),
                               stringsAsFactors = FALSE)
        

        dt_final 是最终输出。

        【讨论】:

        • 非常感谢。我看起来像这样
        • 我很乐意提供帮助。如果这篇文章是你要找的,请接受我的回答。
        猜你喜欢
        • 1970-01-01
        • 2011-02-06
        • 2021-11-24
        • 1970-01-01
        • 2020-08-23
        • 1970-01-01
        • 2019-02-16
        • 1970-01-01
        • 2021-12-28
        相关资源
        最近更新 更多