【问题标题】:Create a new dataframe out of dozens of df.sum() series从几十个 df.sum() 系列中创建一个新的数据框
【发布时间】:2016-05-03 11:44:17
【问题描述】:

我有几个相同格式的 pandas DataFrame,有五列。

我想使用df.sum() 对每个数据帧的值求和。这将为每个数据框创建一个系列,仍然有 5 列。

我的问题是如何获取这些系列,并创建另一个数据框,一列是文件名,其他列是上面来自df.sum()的五列

import pandas as pd
import glob

batch_of_dataframes =  glob.glob("*.txt")

newdf = []
for filename in batch_of_dataframes:
    df = pd.read_csv(filename)
    df['filename'] = str(filename)
    df = df.sum()
    newdf.append(df)

newdf = pd.concat(newdf, ignore_index=True)

不幸的是,这种方法不起作用。 'df['filename'] = str(filename)' 引发 TypeError,并且创建新数据框 newdf 无法正确解析。

如何正确地做到这一点?

如何获取多个pandas.Series 对象并创建DataFrame

【问题讨论】:

  • 您可以发布一些示例数据来模拟您的输入数据框之一吗?这里有几个问题。 1. df.sum() 返回带有len(df.columns) 行的系列(或len(df),具体取决于axis=0 还是1)。系列中没有列。 2. new_df 只是一个系列列表,所以你最终会得到另一个系列。 3. 您应该在df['colname'] = 'value' 上发布完整的回溯。这真的不应该失败。这让我觉得无论出于何种原因,您的数据实际上只是 1 列并作为一个系列被读取,但发布一些示例数据将澄清这一点。
  • 我相信glob.glob('.txt') 正在返回一个空列表。我相信你想要glob.glob('*.txt')
  • @Alexander 对不起,错字
  • @ThomasTu 如何从以“文件名”为列的系列列表转到数据框?我认为这就是问题所在---我不明白这一点

标签: python pandas dataframe series


【解决方案1】:

按此顺序尝试:

  1. 创建一个空列表,比如list_of_series

  2. 对于每个文件:

    1. 加载到数据框中,然后将总和保存在系列中s

    2. 给s添加一个元素:s['filename'] = your_filename

    3. s 附加到list_of_series

  3. 最后,连接(如果需要,还可以转置):

    final_df = pd.concat(list_of_series, axis = 1).T
    

代码

准备工作:

l_df = [pd.DataFrame(np.random.rand(3,5), columns = list("ABCDE")) for _ in range(5)]
for i, df in enumerate(l_df):
    df.to_csv(str(i)+'.txt', index = False)

文件 *.txt 以逗号分隔并包含标题。

! cat 1.txt
A,B,C,D,E
0.18021800981245173,0.29919271590063656,0.09527248614484807,0.9672038093199938,0.07655003742768962
0.35422759068109766,0.04184770882952815,0.682902924462214,0.9400817219440063,0.8825581077493059
0.3762875793116358,0.4745731412494566,0.6545473610147845,0.7479829630649761,0.15641907539706779

实际上,其余部分与您所做的非常相似(我将文件名附加到系列,而不是数据帧。否则它们会被sum() 连接多次):

files = glob.glob('*.txt')
print(files)
['3.txt', '0.txt', '4.txt', '2.txt', '1.txt']

list_of_series = []
for f in files:
    df = pd.read_csv(f)
    s = df.sum()
    s['filename'] = f
    list_of_series.append(s)
final_df = pd.concat(list_of_series, axis = 1).T

print(final_df)
          A         B          C        D        E filename
0    1.0675   2.20957    1.65058  1.80515  2.22058    3.txt
1  0.642805   1.36248  0.0237625  1.87767  1.63317    0.txt
2   1.68678   1.26363   0.835245  2.05305  1.01829    4.txt
3   1.22748   2.09256   0.785089  1.87852  2.05043    2.txt
4  0.910733  0.815614    1.43272  2.65527  1.11553    1.txt

【讨论】:

  • 你能提供代码吗?我相信这大致就是我上面的内容
  • @ShanZhengYang 你来了。我只能推测您的pd.read_csv 出错了:不同格式的文件?或 glob 意外匹配不需要的文件?如果不是这样,我会尝试先在单个文件的循环中运行这三行。
【解决方案2】:

回答这个具体问题:

@ThomasTu 如何从带有“文件名”的系列列表中获取 列到数据框?我认为这就是问题所在---我不明白 这个

它本质上就是您现在所拥有的,但不是附加到一个空列表,而是附加到一个空数据框。如果您不想在每次迭代时重新分配 newdf,我认为有一个 inplace 关键字。

import pandas as pd
import glob

batch_of_dataframes =  glob.glob("*.txt")

newdf = pd.DataFrame()
for filename in batch_of_dataframes:
    df = pd.read_csv(filename)
    df['filename'] = str(filename)
    df = df.sum()
    newdf = newdf.append(df, ignore_index=True)

【讨论】:

    猜你喜欢
    • 2015-03-28
    • 1970-01-01
    • 2017-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多