如何使用公共列值保留多个数据帧中的行?

2024-04-27 18:36:58 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有多个数据帧:

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,其中只包含在同一日期时间内AB列中有值的行?我尝试使用isin函数:

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

但这只是一个单向检查,即只保留A的值,同时datetime存在B的值,但是如果B中有A中不存在的日期时间的额外值,那么这些值将保留在df2中

我可以按相反方向重复此操作以解决此问题:

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

但对于>;2个数据帧(在我目前的工作中,我有大约50个数据帧)这变得非常长且效率低下,因为有必要在全套数据帧之间进行所有可能的成对组合。例如,第三个数据帧df3首先需要对照df1和df2进行检查,但如果它包含的日期时间既不存在于df1中,也不存在于df2中,则反过来需要对照df3重新检查df1和df2

所需的输出是重新定义所有数据帧,使其仅包含具有匹配日期时间值的AB等值


Tags: 数据函数gtdfdatetimedate时间方向
1条回答
网友
1楼 · 发布于 2024-04-27 18:36:58

这是一个连接/合并操作。标准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)

^{tb1}$

相关问题 更多 >