如何保留具有公共列值的多个数据框中的行?
How to retain rows from multiple dataframes with common column value?
假设我有多个数据帧:
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
的值,同时存在 B
的值 datetime
,但如果存在B
中 A
中不存在的日期时间的额外值,然后这些值留在 df2.[=23=] 中
我可以反方向重复操作来解决:
df2 = df2[df2['date'].isin(df1['date'])]
但是对于 >2 个数据帧(我目前的工作中大约有 50 个),这变得非常长且效率低下,因为有必要遍历完整数据帧集之间的所有可能的配对组合。例如,第三个数据帧 df3 首先需要针对 df1 和 df2 进行检查,但是如果它包含的日期时间既不存在于 df1 中也不存在于 df2 中,那么 df1 和 df2 又需要针对 df3 进行重新检查。
期望的输出是重新定义所有数据帧,使它们仅包含 A
、B
等具有匹配日期时间值的值。
这是一个连接/合并操作。标准 Codd 关系 theory/algebra.
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)
datetime
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
假设我有多个数据帧:
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
的值,同时存在 B
的值 datetime
,但如果存在B
中 A
中不存在的日期时间的额外值,然后这些值留在 df2.[=23=] 中
我可以反方向重复操作来解决:
df2 = df2[df2['date'].isin(df1['date'])]
但是对于 >2 个数据帧(我目前的工作中大约有 50 个),这变得非常长且效率低下,因为有必要遍历完整数据帧集之间的所有可能的配对组合。例如,第三个数据帧 df3 首先需要针对 df1 和 df2 进行检查,但是如果它包含的日期时间既不存在于 df1 中也不存在于 df2 中,那么 df1 和 df2 又需要针对 df3 进行重新检查。
期望的输出是重新定义所有数据帧,使它们仅包含 A
、B
等具有匹配日期时间值的值。
这是一个连接/合并操作。标准 Codd 关系 theory/algebra.
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)
datetime | 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 |