如何通过在另一列上应用过滤器来获取列的最小日期或最早日期
How to get minimum date or earliest date of a column by applying filter on another column
我想查找 Vin 列的最早日期。通过在 Value_1 和 Value_2.The 列上应用过滤器 1,日期在另一列 'Date'
中给出
下面是我的数据框。
import pandas as pd
df_merge= pd.DataFrame({'Vin': ['a123', 'a123', 'a123', 'a123', 'b123', 'b123', 'b123', 'b123'],
'Date': ["2022-03-21T15:20:07.536Z", '2022-03-21T15:20:07.510Z', '2022-03-21T15:20:07.535Z',
'2022-03-21T15:20:07.535Z','2022-03-22T09:14:59.615Z','2022-03-22T09:14:59.412Z',
'2022-03-22T09:14:59.512Z','2022-03-22T09:14:59.615Z'],
'Value_1':['1', '0', '1', '1','1', '0', '0', '1'],
'Value_2':['1', '1', '1', '0','1', '0', '1', '1']})
我尝试了一种方法,通过应用所需的过滤器创建另一个数据框,然后使用以下命令获取最短日期。
Temp_table = pd.DataFrame()
Temp_table = df_merge[(df_merge['Value_1'] == 1) & (df_merge['Value_2'] == 1)]
Temp_table['Result'] = np.where(Temp_table.groupby('Vin')['Date'].transform('min').eq(Temp_table['Date']), 'Yes','No')
在此之后,我将此列与我的原始数据框合并。这会创建一个我不想要的非常大的数据框。
所以我的问题是,有没有办法在不创建任何其他 df 的情况下在同一个数据框中获取我的要求。
下面是我预期的带有 'Result' 列的数据框:-
df_merge= pd.DataFrame({'Vin': ['a123', 'a123', 'a123', 'a123', 'b123', 'b123', 'b123', 'b123'],
'Date': ["2022-03-21T15:20:07.536Z", '2022-03-21T15:20:07.510Z', '2022-03-21T15:20:07.535Z',
'2022-03-21T15:20:07.535Z','2022-03-22T09:14:59.615Z','2022-03-22T09:14:59.412Z',
'2022-03-22T09:14:59.512Z','2022-03-22T09:14:59.615Z'],
'Value_1':['1', '0', '1', '1','1', '0', '0', '1'],
'Value_2':['1', '1', '1', '0','1', '0', '1', '1'],
'Result':['No', 'No', 'Yes', 'No','Yes', 'No', 'No', 'Yes']})
df_merge
您可以使用:
更新
idx = (df_merge.assign(Date=pd.to_datetime(df_merge['Date']))
.loc[df_merge['Value_1'].eq('1') & df_merge['Value_2'].eq('1')]
.groupby('Vin')['Date'].rank(method='min')
.loc[lambda x: x == 1].index)
df_merge['Result'] = np.where(df_merge.index.isin(idx), 'Yes', 'No')
旧答案
idx = (df_merge.assign(Date=pd.to_datetime(df_merge['Date']))
.loc[df_merge['Value_1'].eq(1) & df_merge['Value_2'].eq(1)]
.groupby('Vin')['Date'].idxmin())
df_merge['Result'] = np.where(df_merge.index.isin(idx), 'Yes', 'No')
输出:
>>> idx
Vin
a123 2
b123 7
Name: Date, dtype: int64
>>> df_merge
Vin Date Value_1 Value_2 Result
0 a123 2022-03-21T15:20:07.536Z 1 1 No
1 a123 2022-03-21T15:20:07.510Z 0 1 No
2 a123 2022-03-21T15:20:07.535Z 1 1 Yes
3 a123 2022-03-21T15:20:07.535Z 1 0 No
4 b123 2022-03-22T09:14:59.616Z 1 1 No
5 b123 2022-03-22T09:14:59.412Z 0 0 No
6 b123 2022-03-22T09:14:59.512Z 0 1 No
7 b123 2022-03-22T09:14:59.615Z 1 1 Yes
注意:如果 Date
已经是 DatetimeIndex
,您可以安全地删除 assign
方法。
我想查找 Vin 列的最早日期。通过在 Value_1 和 Value_2.The 列上应用过滤器 1,日期在另一列 'Date'
中给出下面是我的数据框。
import pandas as pd
df_merge= pd.DataFrame({'Vin': ['a123', 'a123', 'a123', 'a123', 'b123', 'b123', 'b123', 'b123'],
'Date': ["2022-03-21T15:20:07.536Z", '2022-03-21T15:20:07.510Z', '2022-03-21T15:20:07.535Z',
'2022-03-21T15:20:07.535Z','2022-03-22T09:14:59.615Z','2022-03-22T09:14:59.412Z',
'2022-03-22T09:14:59.512Z','2022-03-22T09:14:59.615Z'],
'Value_1':['1', '0', '1', '1','1', '0', '0', '1'],
'Value_2':['1', '1', '1', '0','1', '0', '1', '1']})
我尝试了一种方法,通过应用所需的过滤器创建另一个数据框,然后使用以下命令获取最短日期。
Temp_table = pd.DataFrame()
Temp_table = df_merge[(df_merge['Value_1'] == 1) & (df_merge['Value_2'] == 1)]
Temp_table['Result'] = np.where(Temp_table.groupby('Vin')['Date'].transform('min').eq(Temp_table['Date']), 'Yes','No')
在此之后,我将此列与我的原始数据框合并。这会创建一个我不想要的非常大的数据框。 所以我的问题是,有没有办法在不创建任何其他 df 的情况下在同一个数据框中获取我的要求。
下面是我预期的带有 'Result' 列的数据框:-
df_merge= pd.DataFrame({'Vin': ['a123', 'a123', 'a123', 'a123', 'b123', 'b123', 'b123', 'b123'],
'Date': ["2022-03-21T15:20:07.536Z", '2022-03-21T15:20:07.510Z', '2022-03-21T15:20:07.535Z',
'2022-03-21T15:20:07.535Z','2022-03-22T09:14:59.615Z','2022-03-22T09:14:59.412Z',
'2022-03-22T09:14:59.512Z','2022-03-22T09:14:59.615Z'],
'Value_1':['1', '0', '1', '1','1', '0', '0', '1'],
'Value_2':['1', '1', '1', '0','1', '0', '1', '1'],
'Result':['No', 'No', 'Yes', 'No','Yes', 'No', 'No', 'Yes']})
df_merge
您可以使用:
更新
idx = (df_merge.assign(Date=pd.to_datetime(df_merge['Date']))
.loc[df_merge['Value_1'].eq('1') & df_merge['Value_2'].eq('1')]
.groupby('Vin')['Date'].rank(method='min')
.loc[lambda x: x == 1].index)
df_merge['Result'] = np.where(df_merge.index.isin(idx), 'Yes', 'No')
旧答案
idx = (df_merge.assign(Date=pd.to_datetime(df_merge['Date']))
.loc[df_merge['Value_1'].eq(1) & df_merge['Value_2'].eq(1)]
.groupby('Vin')['Date'].idxmin())
df_merge['Result'] = np.where(df_merge.index.isin(idx), 'Yes', 'No')
输出:
>>> idx
Vin
a123 2
b123 7
Name: Date, dtype: int64
>>> df_merge
Vin Date Value_1 Value_2 Result
0 a123 2022-03-21T15:20:07.536Z 1 1 No
1 a123 2022-03-21T15:20:07.510Z 0 1 No
2 a123 2022-03-21T15:20:07.535Z 1 1 Yes
3 a123 2022-03-21T15:20:07.535Z 1 0 No
4 b123 2022-03-22T09:14:59.616Z 1 1 No
5 b123 2022-03-22T09:14:59.412Z 0 0 No
6 b123 2022-03-22T09:14:59.512Z 0 1 No
7 b123 2022-03-22T09:14:59.615Z 1 1 Yes
注意:如果 Date
已经是 DatetimeIndex
,您可以安全地删除 assign
方法。