0

假设我有多个数据框:

print (df1)
                datetime    A
0       2012-08-14 07:00    1
1       2012-08-14 07:01    2
2       2012-08-14 08:15    3
                     ...  ...
192908  2013-08-14 16:00  600
192948  2013-08-14 16:15  700
192949  2013-08-14 16:57  900

print (df2)
               datetime    B    
0      2012-08-14 07:00  100
1      2012-08-14 07:15  200
2      2012-08-14 07:30  300
                    ...  ...
12140  2013-09-24 15:45   50
12141  2013-09-24 16:00   60
12142  2013-09-24 16:15   70

如何创建一个新的 df 只包含列中有值的行A并且B在同一日期时间?我尝试使用该isin功能:

df1 = df1[df1['date'].isin(df2['date'])]

但这仅进行单向检查,即仅保留同时A存在 的值的值,但如果日期时间中不存在的额外值则保留在 df2 中。BdatetimeBA

我可以在相反的方向重复操作来解决这个问题:

df2 = df2[df2['date'].isin(df1['date'])]

但是对于 >2 个数据帧(我目前的工作中大约有 50 个),这变得非常冗长且效率低下,因为有必要遍历整个数据帧集之间的每一个可能的配对组合。例如,首先需要对照 df1 和 df2 检查第三个数据帧 df3,但如果它包含既不存在于 df1 也不存在于 df2 中的日期时间,那么 df1 和 df2 将依次需要对照 df3 重新检查。

所需的输出是重新定义所有数据帧,以便它们仅包含具有匹配日期时间值的A、等值。B

4

1 回答 1

1

这是一个连接/合并操作。标准 Codd 关系理论/代数。

import io
df1 = pd.read_csv(io.StringIO("""                datetime    A
0       2012-08-14 07:00    1
1       2012-08-14 07:01    2
2       2012-08-14 08:15    3
192908  2013-08-14 16:00  600
192948  2013-08-14 16:15  700
192949  2013-08-14 16:57  900"""), sep="\s\s+", engine="python")

df2 = pd.read_csv(io.StringIO("""               datetime    B    
0      2012-08-14 07:00  100
1      2012-08-14 07:15  200
2      2012-08-14 07:30  300
12140  2013-09-24 15:45   50
12141  2013-09-24 16:00   60
12142  2013-09-24 16:15   70"""), sep="\s\s+", engine="python")

pd.merge(df1,df2, on="datetime", how="inner")

输出

    datetime    A   B
0   2012-08-14 07:00    1   100

想要合并很多数据框

import io, random, functools

# generate a list of dataframes for merge... start with two sample ones
dfs = [df1, df2]
# generate longer list of dataframes, rename columns to add some interest for merge :-)
dfs = [dfs[random.randint(0, len(dfs)-1)].pipe(lambda d: d.rename(columns={d.columns[1]:f"{d.columns[1]}_{i}"})) for i in range(8)]

# and one line merge the whole list of dataframes
functools.reduce(lambda left,right: pd.merge(left,right,on='datetime'), dfs)

约会时间 A_0 B_1 B_2 B_3 A_4 B_5 B_6 A_7
0 2012-08-14 07:00 1 100 100 100 1 100 100 1
于 2021-05-02T12:45:26.417 回答