Python pandas.merge复制行或列

Python pandas.merge复制行或列,python,pandas,Python,Pandas,我正在尝试将100多个csv文件合并到一个csv文件中。每个文件都有一个时间戳列和一个数据列。有些文件具有相同的数据列,但时间戳不同 通过使用os.walk()搜索目录,然后循环遍历该列表,将每个文件作为数据帧打开,并将其与输出数据帧合并,我得到了一个文件名列表。它开始时为空,但在每个循环上添加数据 以下是代码的要点: output=pd.DataFrame(列=['TimeStamp']) 对于文件列表中的文件名: df=pd.read_csv(文件名,sep=',,skiprows=2,he

我正在尝试将100多个csv文件合并到一个csv文件中。每个文件都有一个时间戳列和一个数据列。有些文件具有相同的数据列,但时间戳不同

通过使用os.walk()搜索目录,然后循环遍历该列表,将每个文件作为数据帧打开,并将其与输出数据帧合并,我得到了一个文件名列表。它开始时为空,但在每个循环上添加数据

以下是代码的要点:

output=pd.DataFrame(列=['TimeStamp'])
对于文件列表中的文件名:
df=pd.read_csv(文件名,sep=',,skiprows=2,header=None,encoding='utf-16')
#转换数据类型
df['TimeStamp']=pd.to_datetime(df['TimeStamp'],dayfirst=True)
df[tag\u name]=pd.to\u numeric(df[tag\u name])
#tag_name来自一个字典,该字典将文件与标签匹配
#以下是我正在尝试的两种方法:
#方法1
output=output.merge(df,how='outer',on='TimeStamp',sort=True)
#方法2-使用tag_name字典中的列初始化输出df
output=output.merge(df,how='outer',on=['TimeStamp',tag_name],sort=True)
下面是一个数据示例:

'TimeStamp',      'Meter 1'
2019-01-01 00:00, 12
2019-01-01 01:00, 17
2019-01-01 02:00, 10
上述3项的预期结果:

'TimeStamp',      'Meter 1', 'Meter 2'
2019-01-01 00:00, 12,        1
2019-01-01 01:00, 17,        6
2019-01-01 02:00, 10,        5
2019-01-01 03:00, 13,
2019-01-01 04:00, 20,
2019-01-01 05:00, 9,
方法1的结果:

'TimeStamp',      'Meter 1', 'Meter 1_x', 'Meter 2'
2019-01-01 00:00, 12,        ,           1
2019-01-01 01:00, 17,        ,           6
2019-01-01 02:00, 10,        ,           5
2019-01-01 03:00, ,          13,
2019-01-01 04:00, ,          20,
2019-01-01 05:00, ,          9,
方法2的结果:

'TimeStamp',      'Meter 1',    'Meter 2'
2019-01-01 00:00, 12,
2019-01-01 00:00, ,              1
2019-01-01 01:00, 17,
2019-01-01 01:00, ,              6
2019-01-01 02:00, 10,
2019-01-01 02:00, ,              5
2019-01-01 03:00, 13,
2019-01-01 04:00, 20,
2019-01-01 05:00, 9,
他们都快到了,但还不完全到。有没有办法通过合并实现这一点,或者我需要完全不同的方法

我试图找出一种方法,将方法1中匹配的列添加到一起,但每次都有不规则的列数。我明天早上再试试这个


编辑: 另一个与回答这个问题相关联的问题,虽然是一个极好的资源,但实际上并没有处理需要合并在一起的重复列名的情况。答案中最接近的部分使用functools.partial的解决方案,但表示如果有重复的列名,可能需要使用lambda,无需进一步详细说明。我不知道如何使用lambda函数实现该解决方案

我在一小部分文件上尝试了这种方法,没有lambda函数它不会失败,但在我自己的代码中产生了与方法2相同的结果。不过,这比我的方法要快得多

从functools导入减少,部分
外部合并=部分(pd.merge,how='outer')
减少(外部合并,dfs)
我认为这是一个问题,因为熊猫认为时间戳不相等。当我将它们作为字符串保留时,同样的事情也会发生

编辑2: 在文本编辑器中看到的实际csv文件的顶部:

"sep=,"
"","Meter_tag",""
"Time","Average(Time Weighted)",""
"01/06/2017 00:00:00","0.000",""
编辑3: 感谢华伦天奴的帮助。我最终使用了一种变通方法,所以我的输出类似于上面的方法2,但我只是每小时对它进行分组,并将多余的行压缩。它只是将实际数据与零相加,因此求和操作不会改变数据

output=output.groupby(pd.Grouper(key='TimeStamp',freq='1H')).sum().reset_index()

这比你想象的要容易

output= output.merge(df, how='outer', sort=True)
只需在关键字参数上删除
。如果
on=None
(默认设置),则会显示:

如果on为None且未在索引上合并,则默认为两个数据帧中的列的交点

使用三个示例文件,它将为您提供:

            TimeStamp        Meter 1        Meter 2
0 2019-01-01 00:00:00             12            1.0
1 2019-01-01 01:00:00             17            6.0
2 2019-01-01 02:00:00             10            5.0
3 2019-01-01 03:00:00             13            NaN
4 2019-01-01 04:00:00             20            NaN
5 2019-01-01 05:00:00              9            NaN

小心:如果某些文件具有重叠的
时间戳
值和相同的列,则将以重复的
时间戳
值结束。您的示例文件中没有介绍这种情况,因此我假设您确信这种情况永远不会发生。

文档中说了这一点,但pandas 0.23.4因MergeError而受阻:没有要执行合并的公共列。合并选项:left\u on=None,right\u on=None,left\u index=False,right\u index=False@SergeBallesta所以这是一个版本问题/bug?我用的是熊猫0.24,我发布的内容对我有用。我相信是的。你的解决方案真的很整洁。我留下评论是为了警告未来的读者,他们可能需要升级熊猫的旧版本。谢谢你的回答,但不幸的是,这产生了与问题中方法2相同的结果。我使用的是熊猫0.24.1。在实际数据中,每个文件中有6个月。它合并了前6个月的罚款,但剩余的3年与方法2相同。在“米1”的前6个月,然后是“米1”的后6个月,依此类推,直到“米2”开始之前,所有米1都完成。实际的问题可能是,它不承认时间戳是相等的吗?我只是想知道。。。为什么读取csv文件时会出现
skiprows=2
header=None
?你真的跳过标题了吗?您能尝试一下删除此参数并读取标题会发生什么情况吗?
output= output.merge(df, how='outer', sort=True)
            TimeStamp        Meter 1        Meter 2
0 2019-01-01 00:00:00             12            1.0
1 2019-01-01 01:00:00             17            6.0
2 2019-01-01 02:00:00             10            5.0
3 2019-01-01 03:00:00             13            NaN
4 2019-01-01 04:00:00             20            NaN
5 2019-01-01 05:00:00              9            NaN