【问题标题】:Pandas: import multiple csv files into dataframe using a loop and hierarchical indexingPandas:使用循环和分层索引将多个 csv 文件导入数据帧
【发布时间】:2014-02-04 15:50:00
【问题描述】:

我想将目标目录中的多个 CSV 文件(具有不同列数)读取到单个 Python Pandas DataFrame 中,以有效地搜索和提取数据。

示例文件:

Events 
1,0.32,0.20,0.67
2,0.94,0.19,0.14,0.21,0.94
3,0.32,0.20,0.64,0.32
4,0.87,0.13,0.61,0.54,0.25,0.43 
5,0.62,0.21,0.77,0.44,0.16

这是我目前所拥有的:

# get a list of all csv files in target directory
my_dir = "C:\\Data\\"
filelist = []
os.chdir( my_dir )
for files in glob.glob( "*.csv" ) :
    filelist.append(files)

# read each csv file into single dataframe and add a filename reference column 
# (i.e. file1, file2, file 3) for each file read
df = pd.DataFrame()
columns = range(1,100)
for c, f in enumerate(filelist) :
    key = "file%i" % c
    frame = pd.read_csv( (my_dir + f), skiprows = 1, index_col=0, names=columns )
    frame['key'] = key
    df = df.append(frame,ignore_index=True)

(索引无法正常工作)

基本上,下面的脚本正是我想要的(经过试验和测试),但需要循环遍历 10 个或更多 csv 文件:

df1 = pd.DataFrame()
df2 = pd.DataFrame()
columns = range(1,100)
df1 = pd.read_csv("C:\\Data\\Currambene_001y09h00m_events.csv", 
                  skiprows = 1, index_col=0, names=columns)
df2 = pd.read_csv("C:\\Data\\Currambene_001y12h00m_events.csv", 
                  skiprows = 1, index_col=0, names=columns)
keys = [('file1'), ('file2')]
df = pd.concat([df1, df2], keys=keys, names=['fileno'])

我找到了许多相关链接,但是我仍然无法使其正常工作:

【问题讨论】:

  • pandas.concat 将允许您使用包含 DataFrame 的任意长度的列表。使用包含所有文件的单个列表提供第一个参数,您将不必再循环脚本。

标签: python csv pandas hierarchical-data


【解决方案1】:

您需要决定要在哪个轴上附加文件。 Pandas 将始终尝试通过以下方式做正确的事情:

  1. 假设每个文件中的每一列都不同,必要时将数字附加到文件中名称相似的列中,以免混淆;
  2. 文件中属于同一行索引的项目并排放置在各自的列下。

高效追加的诀窍是将文件倾斜,这样您就可以获得与pandas.concat 将要执行的操作相匹配的所需行为。这是我的食谱:

from pandas import *
files = !ls *.csv # IPython magic
d = concat([read_csv(f, index_col=0, header=None, axis=1) for f in files], keys=files)

注意read_csvaxis=1 转置,因此它将在列轴上连接,保留其名称。如果需要,可以使用d.T 将生成的 DataFrame 转回。

编辑:

对于每个源文件中不同的列数,您需要提供一个标题。我知道您的源文件中没有标题,所以让我们用一个简单的函数创建一个:

def reader(f):
    d = read_csv(f, index_col=0, header=None, axis=1)
    d.columns = range(d.shape[1])
    return d

df = concat([reader(f) for f in files], keys=files)

【讨论】:

  • 当每一行都有相同的列数时,效果很好。对不同的列长度有什么建议??? d = pd.concat([(read_csv((TP_dir + f), index_col=0, header=0).T) for f in filelist], keys=filelist)
  • 这是一个不错的 ipython 技巧! ...你不能使用axis = 1来连接以避免.T吗?
  • @mellover,给它一个标题。来自文件或范围,就像您在脚本中所做的那样。
  • @AndyHayden,是的!当我用concat 尝试axis = 1 并失败时,我一定是在使用pandas 0.12 或做其他错误。不是它有效。 :)
  • 调整后完美运行。谢谢
猜你喜欢
  • 2021-12-16
  • 1970-01-01
  • 2020-08-05
  • 1970-01-01
  • 2022-12-17
  • 2019-11-23
  • 1970-01-01
  • 1970-01-01
  • 2021-04-17
相关资源
最近更新 更多