给定一个 Pandas 数据框 df1
column_name id column_value from_date to_date
0 score 8 B 2021-01-01 2021-01-04
1 score 8 B+ 2021-01-05 2021-01-10
2 score 9 Z 2021-01-01 2021-01-10
和另一个df2
column_name id column_value from_date to_date
0 score 8 AAAAAAA-override 2021-01-03 2021-01-07
1 score 9 B+-override 2021-01-08 2021-01-10
我想创建一个由 id
分组并组合 df1
和 df2
之间重叠日期范围的新数据框。如果重叠,我将采用 df2 的 column_value
。
最终结果是df
:
from_date to_date id column_value
index
1 2021-01-01 2021-01-02 8 B
2 2021-01-03 2021-01-07 8 AAAAAAA-override
3 2021-01-08 2021-01-10 8 B+
4 2021-01-01 2021-01-07 9 Z
5 2021-01-08 2021-01-10 9 B+-override
我目前的解决方案很慢,因为我将每个日期从 from_date
添加到 to_date
,然后我重叠两个数据框和 groupby
新日期并从 { {1}}。然后我将结果压缩回一个 from 和一个 to。
这不适用于我们拥有的数据类型,我们可以拥有超过 10 万个 ID,并且日期范围非常广泛:从 1900 年 1 月 1 日到今天。
谁能想到更具可扩展性的解决方案?也许使用 df2
还是我应该使用普通的 python?
答案 0 :(得分:1)
assign()
可以是必需的列,另外可以删除 O 列df1 = pd.read_csv(io.StringIO(""" column_name id column_value from_date to_date
0 score 8 B 2021-01-01 2021-01-04
1 score 8 B+ 2021-01-05 2021-01-10
2 score 9 Z 2021-01-01 2021-01-10"""), sep="\s+")
df1.from_date = pd.to_datetime(df1.from_date)
df1.to_date = pd.to_datetime(df1.to_date)
df2 = pd.read_csv(io.StringIO(""" column_name id column_value from_date to_date
0 score 8 AAAAAAA-override 2021-01-03 2021-01-07
1 score 9 B+-override 2021-01-08 2021-01-10"""), sep="\s+")
df2.from_date = pd.to_datetime(df2.from_date)
df2.to_date = pd.to_datetime(df2.to_date)
df3 = pd.concat([df1.assign(O=False),df2.assign(O=True)]).sort_values(["id","from_date","to_date"])
df3 = df3.groupby(["id"]).apply(lambda dfa: dfa.assign(
new_from_date=np.where(~dfa.O & dfa.O.shift(),
dfa.to_date.shift()+pd.Timedelta(days=1),
dfa.from_date),
new_to_date=np.where(~dfa.O & dfa.O.shift(-1),
dfa.from_date.shift(-1)-pd.Timedelta(days=1),
dfa.to_date),
)).reset_index(drop=True)
column_name | id | column_value | from_date | to_date | O | new_from_date | new_to_date | |
---|---|---|---|---|---|---|---|---|
0 | 得分 | 8 | B | 2021-01-01 00:00:00 | 2021-01-04 00:00:00 | 假 | 2021-01-01 00:00:00 | 2021-01-02 00:00:00 |
1 | 得分 | 8 | AAAAAAA-override | 2021-01-03 00:00:00 | 2021-01-07 00:00:00 | 真 | 2021-01-03 00:00:00 | 2021-01-07 00:00:00 |
2 | 得分 | 8 | B+ | 2021-01-05 00:00:00 | 2021-01-10 00:00:00 | 假 | 2021-01-08 00:00:00 | 2021-01-10 00:00:00 |
3 | 得分 | 9 | Z | 2021-01-01 00:00:00 | 2021-01-10 00:00:00 | 假 | 2021-01-01 00:00:00 | 2021-01-07 00:00:00 |
4 | 得分 | 9 | B+-override | 2021-01-08 00:00:00 | 2021-01-10 00:00:00 | 真 | 2021-01-08 00:00:00 | 2021-01-10 00:00:00 |