在 pandas 中,如何使用从其他列中提取的模式来填充 Nan?
In pandas, how to fill Nan with a pattern extract from an other column?
我正在处理下面的数据,我想在 Begin
和 End
中的 Nan 中填写 Subscription Period
列中的日期。
所有列都是字符串。
我有几种格式:
- 对于
05/03/2020 to 04/03/2021
,我使用:
# clean if date begin and end in SubscriptionPeriod
# create 3 new colonnes
df_period = df['Subscription Period'] \
.str.extractall(r'(?P<Period>(?P<Begin>(0[1-9]|[12][0-9]|3[01])[/](0[1-9]|1[012])[/](19|20)?\d\d).+(?P<End>(0[1-9]|[12][0-9]|3[01])[/](0[1-9]|1[012])[/](19|20)?\d\d))')
df['Period'] = df_period['Period'].unstack()
df['Begin'] = df_period['Begin'].unstack()
df['End'] = df_period['End'].unstack()
- 对于
Subscription Period
中的其他格式:
Subscription Hospital Sept-Dec 2018
:我想在 Begin
中将 Sept 提取为 01/09/2018,在 End
中提取为 2018 年 12 月 31 日。
Yearly Subscription Hospital (effective 17/04/2019)
Yearly Subscription Hospital (effective 01 octobre 2018)
对于这两次,我想在 Begin
中获取日期,在 End
中获取一年以上的日期。
我尝试解决方案:
- 带掩码()
mask = df['Subscription Period'].str.contains(r'(\d{2}/\d{2}/\d{2,4})[)]?$')
df.loc[mask, 'Begin'] = df['Subscription Period'].str.contains(r'(\d{2}/\d{2}/\d{2,4})[)]?$')
- with loc():适用于 'B' 但不适用于带提取的正则表达式。
df.loc[(df['Begin'].isnull()) , 'Period']= 'B'
这里是数据:
data = {'Date': {0: '2020-05-05',
1: '2018-09-12',
2: '2020-04-22',
3: '2020-01-01',
4: '2019-04-17',
5: '2018-09-07',
6: '2018-11-20',
7: '2018-11-28'},
'Subscription Period': {0: 'Subscription Hospital : from 01/05/2020 to 30/04/2021',
1: 'Subscription Hospital Sept-Dec 2018',
2: 'Yearly Subscription Hospital from 05/03/2020 to 04/03/2021',
3: 'Subscription Hospital from 01/01/2020 to 31/12/2020',
4: 'Yearly Subscription Hospital (effective 17/04/2019)',
5: 'Yearly Subscription Hospital (effective 01 octobre 2018)',
6: 'Subscription : Hospital',
7: 'Yearly Subscription Hospital'},
'Period': {0: '01/05/2020 to 30/04/2021',
1: np.NaN,
2: '05/03/2020 to 04/03/2021',
3: '01/01/2020 to 31/12/2020',
4: np.NaN,
5: np.NaN,
6: np.NaN,
7: np.NaN},
'Begin': {0: '01/05/2020',
1: np.NaN,
2: '05/03/2020',
3: '01/01/2020',
4: np.NaN,
5: np.NaN,
6: np.NaN,
7: np.NaN},
'End': {0: '30/04/2021',
1: np.NaN,
2: '04/03/2021',
3: '31/12/2020',
4: np.NaN,
5: np.NaN,
6: np.NaN,
7: np.NaN}}
df = pd.DataFrame.from_dict(data)
感谢您的帮助和任何提示。
关于您的 mask
示例,如果您使用的是 str.extract
或 str.extractall
,则无需使用掩码进行索引,因为生成的数据帧已被索引。相反,您可以使用 concat
加入索引并使用 combine_first
仅在 Begin
为空的情况下应用:
begin2 = df['Subscription Period'].str.extract(r'(\d{2}/\d{2}/\d{2,4})[)]?$').rename({0:'Begin2'}, axis=1)
df = pd.concat([df, begin2], axis=1)
df.Begin = df.Begin.combine_first(df.Begin2)
df = df.drop('Begin2', axis=1)
希望你能从这里拿走它?否则你可能需要澄清你到底在哪里遇到了问题。
顺便说一句,那些正则表达式非常多毛。我建议转换定义自定义函数并使用 df.apply
.
我正在处理下面的数据,我想在 Begin
和 End
中的 Nan 中填写 Subscription Period
列中的日期。
所有列都是字符串。
我有几种格式:
- 对于
05/03/2020 to 04/03/2021
,我使用:
# clean if date begin and end in SubscriptionPeriod
# create 3 new colonnes
df_period = df['Subscription Period'] \
.str.extractall(r'(?P<Period>(?P<Begin>(0[1-9]|[12][0-9]|3[01])[/](0[1-9]|1[012])[/](19|20)?\d\d).+(?P<End>(0[1-9]|[12][0-9]|3[01])[/](0[1-9]|1[012])[/](19|20)?\d\d))')
df['Period'] = df_period['Period'].unstack()
df['Begin'] = df_period['Begin'].unstack()
df['End'] = df_period['End'].unstack()
- 对于
Subscription Period
中的其他格式:
Subscription Hospital Sept-Dec 2018
:我想在 Begin
中将 Sept 提取为 01/09/2018,在 End
中提取为 2018 年 12 月 31 日。
Yearly Subscription Hospital (effective 17/04/2019)
Yearly Subscription Hospital (effective 01 octobre 2018)
对于这两次,我想在 Begin
中获取日期,在 End
中获取一年以上的日期。
我尝试解决方案:
- 带掩码()
mask = df['Subscription Period'].str.contains(r'(\d{2}/\d{2}/\d{2,4})[)]?$')
df.loc[mask, 'Begin'] = df['Subscription Period'].str.contains(r'(\d{2}/\d{2}/\d{2,4})[)]?$')
- with loc():适用于 'B' 但不适用于带提取的正则表达式。
df.loc[(df['Begin'].isnull()) , 'Period']= 'B'
这里是数据:
data = {'Date': {0: '2020-05-05',
1: '2018-09-12',
2: '2020-04-22',
3: '2020-01-01',
4: '2019-04-17',
5: '2018-09-07',
6: '2018-11-20',
7: '2018-11-28'},
'Subscription Period': {0: 'Subscription Hospital : from 01/05/2020 to 30/04/2021',
1: 'Subscription Hospital Sept-Dec 2018',
2: 'Yearly Subscription Hospital from 05/03/2020 to 04/03/2021',
3: 'Subscription Hospital from 01/01/2020 to 31/12/2020',
4: 'Yearly Subscription Hospital (effective 17/04/2019)',
5: 'Yearly Subscription Hospital (effective 01 octobre 2018)',
6: 'Subscription : Hospital',
7: 'Yearly Subscription Hospital'},
'Period': {0: '01/05/2020 to 30/04/2021',
1: np.NaN,
2: '05/03/2020 to 04/03/2021',
3: '01/01/2020 to 31/12/2020',
4: np.NaN,
5: np.NaN,
6: np.NaN,
7: np.NaN},
'Begin': {0: '01/05/2020',
1: np.NaN,
2: '05/03/2020',
3: '01/01/2020',
4: np.NaN,
5: np.NaN,
6: np.NaN,
7: np.NaN},
'End': {0: '30/04/2021',
1: np.NaN,
2: '04/03/2021',
3: '31/12/2020',
4: np.NaN,
5: np.NaN,
6: np.NaN,
7: np.NaN}}
df = pd.DataFrame.from_dict(data)
感谢您的帮助和任何提示。
关于您的 mask
示例,如果您使用的是 str.extract
或 str.extractall
,则无需使用掩码进行索引,因为生成的数据帧已被索引。相反,您可以使用 concat
加入索引并使用 combine_first
仅在 Begin
为空的情况下应用:
begin2 = df['Subscription Period'].str.extract(r'(\d{2}/\d{2}/\d{2,4})[)]?$').rename({0:'Begin2'}, axis=1)
df = pd.concat([df, begin2], axis=1)
df.Begin = df.Begin.combine_first(df.Begin2)
df = df.drop('Begin2', axis=1)
希望你能从这里拿走它?否则你可能需要澄清你到底在哪里遇到了问题。
顺便说一句,那些正则表达式非常多毛。我建议转换定义自定义函数并使用 df.apply
.