在python中合并具有不同长度和列的数据框列表

Posted

技术标签:

【中文标题】在python中合并具有不同长度和列的数据框列表【英文标题】:Merging a list of dataframes with different lengths and columns in python 【发布时间】:2019-12-21 05:35:49 【问题描述】:

我有 100 个数据帧的列表,我试图合并到一个数据帧中,但我无法这样做。所有数据框都有不同的列并且长度不同。为了提供一些上下文和背景,每个数据帧都包含 4 个情绪分数(使用 VaderSentiment 计算)。数据框具有以下表示:

用户 1 数据框

created_at       | positive score of user 1 tweets  |  negative score of user 1   tweets|    neutral score of user 1 tweets  | compound score of user 1 tweets |
23/2/2011 10:00  |           1.12                   |            1.3                    |                1.0                 |                  3.3            |
24/2/2011 11:00  |           1.20                   |            1.1                    |                0.9                 |                  2.5            |

用户 2 数据框

created_at       | positive score of user 1 tweets  |  negative score of user 1   tweets|    neutral score of user 1 tweets  | compound score of user 1 tweets |
25/3/2011 23:00  |           0.12                   |            1.1                    |                0.1                 |                  1.1            |
26/3/2011 08:00  |           1.40                   |            1.5                    |                0.4                 |                  1.5            |
01/4/2011 19:00  |           1.80                   |            0.1                    |                1.9                 |                  3.9            |

所有数据框都有一个列共同,即created_at。我想要实现的是合并基于 created_at 列的所有数据框,以便我得到 只有一个 created_at 列和来自所有其他数据框的所有其他列。结果应该有 **400* 列的情绪分数以及 created_at 列。

我的代码如下:

import pandas as pd
import glob
import numpy as np
import os
from functools import reduce


path = r'C:\Users\Desktop\Tweets'
allFiles = glob.glob(path + "/*.csv")
list = []
frame = pd.DataFrame()

count=0

for f in allFiles:
    file = open(f, 'r')
    count=count+1
    _, fname = os.path.split(f)
    df = pd.read_csv(f)
    #print(df)
    list.append(df)

frame = pd.concat(list)
print(frame)

问题是,当我运行上述代码时,我得到了所需的列排列,但我没有得到值,而是在所有值中得到 NaN,因此基本上有一个包含 401 列的数据框,其中只有created_at 列包含值

感谢任何和所有的帮助。

谢谢

编辑

我已经尝试了各种不同的解决方案来解决这里发布的不同问题,但似乎都没有奏效,因此作为最后的手段,我开始了这个帖子

编辑 2

我也许想出了解决我的问题的方法。使用下面的代码,我可以将所有列附加到frames。但是,这会创建 created_at 列的副本,该列恰好是 object 类型。如果我能把所有的日期合并到一个列中,那么我的问题就离解决更近了。

for f in allFiles :
file = open(f, 'r')
count=count+1
_, fname = os.path.split(f)
df = pd.read_csv(f)

dates = df.iloc[:,0]
neut = df.iloc[:,1]
pos = df.iloc[:,2]
neg = df.iloc[:,3]
comp = df.iloc[:,4]

all_frames.append(dates)
all_frames.append(neut)
all_frames.append(pos)
all_frames.append(neg)
all_frames.append(comp)

frame = pd.concat(all_frames,axis=1)

任何帮助将不胜感激

【问题讨论】:

Pandas Merging 101的可能重复 底线,您不应该将append() 用于数据帧,这听起来像是直截了当的merge(),否则,concat() Efficient chain merge in pandas的可能重复 @G.Anderson 我确实使用过 concat。在代码中使用append 是一个打字错误 在你的情况下,它会像pd.concat([pd.read_csv(f).set_index("created_at", drop=True) for f in allFiles], axis=1) 【参考方案1】:

我强烈建议您修改您的数据模型。拥有这么多列通常表明有问题。话虽如此,这是一种方法。 list 也是一种内置数据类型。不要用变量名覆盖它。

我假设除了created_at,每个文件的列都是唯一的。

all_frames = []
for f in allFiles:
    file = open(f, 'r')
    count=count+1
    _, fname = os.path.split(f)
    df = pd.read_csv(f, parse_dates=['created_at'], index_col='created_at')
    all_frames.append(df)

# This will create a dataframe of size n * 400
# n is the total number of rows between all files
frame = pd.concat(all_frames, join='outer', copy=False, sort=False)

# If you want to line up the hour across all users
frame.groupby(level=0)[frame.columns].first()

【讨论】:

您正确地假设除了 created_at 列之外,所有数据框都有唯一的列。但是,尝试这个,我得到了与我最初得到的相同的错误。我最终得到 400 列而不是 401 列,除了 created_at 列之外,所有其他列都有 NaN 值。此外,print(all_frames) 打印所有 100 个数据帧,其中 4 列而不是 5 列。 我已经编辑了我的原始帖子以使用 部分 解决方案对其进行更新。我需要能够将 100 个 created_at 列合并为一个。如果我能做到这一点,那么我也许能够解决问题

以上是关于在python中合并具有不同长度和列的数据框列表的主要内容,如果未能解决你的问题,请参考以下文章

熊猫用不同的列python连接数据框列表

合并两个不同长度的python pandas数据帧,但将所有行保留在输出数据帧中

Pandas 将具有多个值的行数据合并到列的 Python 列表中

Python Pandas - 具有不同列的 Concat 数据框忽略列名

Pandas 合并具有不同列的两个数据框

每次合并具有不同列名的熊猫数据框列表