Pandas 对列表应用多项功能
Pandas apply multiple function with list
我有一个带有 'File_name' 列的 df,其中包含我想解析的文件名字符串:
data = [['f1h3_13oct2021_gt1.csv', 2], ['p8-gfr-20dec2021-81.csv', 0.5]]
df= pd.DataFrame(data, columns = ['File_name', 'Result'])
df.head()
现在我想创建一个新列,在其中使用“_”和“-”分隔符解析文件名,然后在结果列表中搜索我可以在日期时间对象中转换的字符串。命名约定并不总是相同的(不同的顺序,所以我不能依赖字符串字符的位置)并且代码应该包括一个“尝试”转换为日期时间,因为通常应该是日期的字符串是错误的格式或丢失。
我想到了以下内容,但它对我来说并不像 pythonic
# Solution #1
for i, value in df['File_name'].iteritems():
chunks = value.split('-') + value.split('_')
for chunk in chunks:
try:
df.loc[i,'Date_Sol#1'] = dt.datetime.strptime(chunk, '%d%b%Y')
except:
pass
df.head()
或者,我试图将 apply 方法与这两个函数一起使用我真的想不出解决这两个函数链接和 try - pass 语句的方法,但我真的没能让它工作
# Solution #2
import re
splitme = lambda x: re.split('_|-', x)
calcdate = lambda x : dt.datetime.strptime(x, '%d%b%Y')
df['t1'] = df['File_name'].apply(splitme)
df['Date_Sol#2'] =df['t1'].apply(lambda x: calcdate(x) for x in df['t1'] if isinstance(calcdate(x),dt.datetime) else Pass)
df.head()
我认为列表理解可能有帮助?
解决方案 #2 的外观有什么帮助吗?
提前致谢
假设你想提取和转换可能的块作为日期,你可以 split
the string on delimiters, explode
to multiple rows and attempt to convert to date with pandas.to_datetime
:
df.join(pd
.to_datetime(df['File_name']
.str.split(r'[_-]')
.explode(), errors='coerce')
.dropna().rename('Date')
)
输出:
File_name Result Date
0 f1h3_13oct2021_gt1.csv 2.0 2021-10-13
1 p8-gfr-20dec2021-81.csv 0.5 2021-12-20
注意。如果每个字符串可能有很多日期,则需要向 select 添加一个你想要的步骤。如果是这种情况,请提供更多详细信息。
python 旧版本 pandas
import re
s = pd.Series([next(iter(pd.to_datetime(re.split(r'[._-]', s), errors='coerce')
.dropna()), float('nan'))
for s in df['File_name']], index=df.index, name='date')
df.join(s)
我有一个带有 'File_name' 列的 df,其中包含我想解析的文件名字符串:
data = [['f1h3_13oct2021_gt1.csv', 2], ['p8-gfr-20dec2021-81.csv', 0.5]]
df= pd.DataFrame(data, columns = ['File_name', 'Result'])
df.head()
现在我想创建一个新列,在其中使用“_”和“-”分隔符解析文件名,然后在结果列表中搜索我可以在日期时间对象中转换的字符串。命名约定并不总是相同的(不同的顺序,所以我不能依赖字符串字符的位置)并且代码应该包括一个“尝试”转换为日期时间,因为通常应该是日期的字符串是错误的格式或丢失。 我想到了以下内容,但它对我来说并不像 pythonic
# Solution #1
for i, value in df['File_name'].iteritems():
chunks = value.split('-') + value.split('_')
for chunk in chunks:
try:
df.loc[i,'Date_Sol#1'] = dt.datetime.strptime(chunk, '%d%b%Y')
except:
pass
df.head()
或者,我试图将 apply 方法与这两个函数一起使用我真的想不出解决这两个函数链接和 try - pass 语句的方法,但我真的没能让它工作
# Solution #2
import re
splitme = lambda x: re.split('_|-', x)
calcdate = lambda x : dt.datetime.strptime(x, '%d%b%Y')
df['t1'] = df['File_name'].apply(splitme)
df['Date_Sol#2'] =df['t1'].apply(lambda x: calcdate(x) for x in df['t1'] if isinstance(calcdate(x),dt.datetime) else Pass)
df.head()
我认为列表理解可能有帮助? 解决方案 #2 的外观有什么帮助吗? 提前致谢
假设你想提取和转换可能的块作为日期,你可以 split
the string on delimiters, explode
to multiple rows and attempt to convert to date with pandas.to_datetime
:
df.join(pd
.to_datetime(df['File_name']
.str.split(r'[_-]')
.explode(), errors='coerce')
.dropna().rename('Date')
)
输出:
File_name Result Date
0 f1h3_13oct2021_gt1.csv 2.0 2021-10-13
1 p8-gfr-20dec2021-81.csv 0.5 2021-12-20
注意。如果每个字符串可能有很多日期,则需要向 select 添加一个你想要的步骤。如果是这种情况,请提供更多详细信息。
python 旧版本 pandas
import re
s = pd.Series([next(iter(pd.to_datetime(re.split(r'[._-]', s), errors='coerce')
.dropna()), float('nan'))
for s in df['File_name']], index=df.index, name='date')
df.join(s)