Dataframe 列定位 ID 的最小值和最大值
Dataframe column locating min and max value depeding of an ID
我想知道如何优化部分代码以删除一个循环,因为我有大约 350 000 个 ID。
这是当前代码,它不是最优的并且需要相当长的时间。
我正在努力让它更好地工作,如果可能的话删除循环。
数据集由 4 列组成,ID 为 start_dates、end_dates 和金额。我们可以有多个 ID 相同但数量不同的行。最主要的是在某些行中,日期未保存在数据集中。在这种情况下,我们必须找到 ID 中较早的 start_date 和较晚的 end_date 并将它们添加到未放入数据框的行中
ID start_date end_date value
ABC 12/10/2010 12/12/2020 8
ABC 01/01/2020 01/04/2021 9
ABC 43
BCD 14/02/2020 14/03/2020 8
所以我们应该在第三行将 start_date 作为 12/10/2010 和结束日期 01/04/2021。在图片中你看不到它但不要忘记 BCD start_date 可能早于 ABC 但你仍然使用 12/10/2010 因为它链接到 ID
for x in df['ID'].unique():
tmp = df.loc[df['ID'] == x].reset_index()
df.loc[(df['ID'] == x) & (df['start_date'].isna()), 'start_date'] = tmp['start_date'].min()
df.loc[(df['ID'] == x) & (df['end_date'].isna()), 'end_date'] = tmp['end_date'].max()
我想代码很清楚我想做什么。
但是,如果您有任何问题,请不要犹豫,post 我会尽力回答。
设置作业
import pandas as pd
data = { 'ID': ['ABC','ABC','ABC','BCD'], 'start_date' : ['12/10/2010', '01/01/2020',None ,'14/02/2020'], 'end_date': ['12/12/2020', '01/01/2021',None ,'14/03/2020'], 'value': [8,9,43,8]}
df = pd.DataFrame(data)
df['start_date'] = pd.to_datetime(df['start_date'])
df['end_date'] = pd.to_datetime(df['end_date'])
我们得到这个结果
ID start_date end_date value
0 ABC 2010-12-10 2020-12-12 8
1 ABC 2020-01-01 2021-01-01 9
2 ABC NaT NaT 43
3 BCD 2020-02-14 2020-03-14 8
完成工作
df.start_date = df.groupby('ID')['start_date'].apply(lambda x: x.fillna(x.min()))
df.end_date = df.groupby('ID')['end_date'].apply(lambda x: x.fillna(x.max()))
我们得到这个结果
ID start_date end_date value
0 ABC 2010-12-10 2020-12-12 8
1 ABC 2020-01-01 2021-01-01 9
2 ABC 2010-12-10 2021-01-01 43
3 BCD 2020-02-14 2020-03-14 8
我想知道如何优化部分代码以删除一个循环,因为我有大约 350 000 个 ID。 这是当前代码,它不是最优的并且需要相当长的时间。 我正在努力让它更好地工作,如果可能的话删除循环。
数据集由 4 列组成,ID 为 start_dates、end_dates 和金额。我们可以有多个 ID 相同但数量不同的行。最主要的是在某些行中,日期未保存在数据集中。在这种情况下,我们必须找到 ID 中较早的 start_date 和较晚的 end_date 并将它们添加到未放入数据框的行中
ID start_date end_date value
ABC 12/10/2010 12/12/2020 8
ABC 01/01/2020 01/04/2021 9
ABC 43
BCD 14/02/2020 14/03/2020 8
所以我们应该在第三行将 start_date 作为 12/10/2010 和结束日期 01/04/2021。在图片中你看不到它但不要忘记 BCD start_date 可能早于 ABC 但你仍然使用 12/10/2010 因为它链接到 ID
for x in df['ID'].unique():
tmp = df.loc[df['ID'] == x].reset_index()
df.loc[(df['ID'] == x) & (df['start_date'].isna()), 'start_date'] = tmp['start_date'].min()
df.loc[(df['ID'] == x) & (df['end_date'].isna()), 'end_date'] = tmp['end_date'].max()
我想代码很清楚我想做什么。 但是,如果您有任何问题,请不要犹豫,post 我会尽力回答。
设置作业
import pandas as pd
data = { 'ID': ['ABC','ABC','ABC','BCD'], 'start_date' : ['12/10/2010', '01/01/2020',None ,'14/02/2020'], 'end_date': ['12/12/2020', '01/01/2021',None ,'14/03/2020'], 'value': [8,9,43,8]}
df = pd.DataFrame(data)
df['start_date'] = pd.to_datetime(df['start_date'])
df['end_date'] = pd.to_datetime(df['end_date'])
我们得到这个结果
ID start_date end_date value
0 ABC 2010-12-10 2020-12-12 8
1 ABC 2020-01-01 2021-01-01 9
2 ABC NaT NaT 43
3 BCD 2020-02-14 2020-03-14 8
完成工作
df.start_date = df.groupby('ID')['start_date'].apply(lambda x: x.fillna(x.min()))
df.end_date = df.groupby('ID')['end_date'].apply(lambda x: x.fillna(x.max()))
我们得到这个结果
ID start_date end_date value
0 ABC 2010-12-10 2020-12-12 8
1 ABC 2020-01-01 2021-01-01 9
2 ABC 2010-12-10 2021-01-01 43
3 BCD 2020-02-14 2020-03-14 8