我有一个大型数据框,其中包含 百万条记录 ,
列表是,
image_jpg= ['image/jpeg','image/jpg','image/pjpeg']
image_png = ['image/png','image/x-png','application/png']
image_gif = ['image/gif']
我想制作名为name
的新列,例如:
索引0 的content_type
值image/jpeg
在列表中 image_jpg
,因此name
列获取价值的5efc61356f85e500694bcbbbbb3ee4c2.jpg
(sys_id
+ .jpg
)
现在我是通过实现的:
file_name = []
for index, row in df.iterrows():
if row['content_type'] in image_jpg:
file_name.append(str(row['sys_id'])+'.jpg')
elif row['content_type'] in image_png:
file_name.append(str(row['sys_id'])+'.png')
elif row['content_type'] in image_png:
file_name.append(str(row['sys_id'])+'.gif')
else:
file_name.append(str(row['sys_id']))
df['name'] = file_name
输出:
问题在于,由于数据帧非常大,因此需要花费很长时间。
是否有更快的方法来完成此任务?
答案 0 :(得分:1)
使用字典和按列操作:
d = {'image_jpg': ['image/jpeg','image/jpg','image/pjpeg'],
'image_png': ['image/png','image/x-png','application/png'],
'image_gif': ['image/gif']}
d_rev = {w: k for k, v in d.items() for w in v}
for k, v in d_rev.items():
mask = df['content_type'].str.contains(v, regex=False)
df.loc[mask, 'name'] = df.loc[mask, 'sys_id'] + '.' + k.split('/')[-1]
或者,如果需要相等:
for k, v in d_rev.items():
mask = df['content_type'].eq(v)
df.loc[mask, 'name'] = df.loc[mask, 'sys_id'] + '.' + k.split('/')[-1]
对于平等情况,@AntonvBR's pd.Series.map
solution更好。
说明
d_rev
将每个列表值映射到一个键:-
print(d_rev)
{'application/png': 'image_png', 'image/gif': 'image_gif',
'image/jpeg': 'image_jpg', 'image/jpg': 'image_jpg',
'image/pjpeg': 'image_jpg', 'image/png': 'image_png',
'image/x-png': 'image_png'}
鉴于类别很少,行数很多,因此迭代字典和使用优化的逐列运算更为有效。请记住,iterrows
只是一个缓慢的逐行循环,对于大量行它总是效率低下。
答案 1 :(得分:1)
我会将您的列表重组为字典并使用map:
df['name'] = df['id'] + df['content_type'].map(d).fillna('')
感谢@jezrael,我们还应该添加fillna('')来处理错误。
这意味着您应使用以下内容替换列表:
d = {
'application/png': '.png',
'image/gif': '.gif',
'image/jpeg': '.jpg',
'image/jpg': '.jpg',
'image/pjpeg': '.jpg',
'image/png': '.png',
'image/x-png': '.png',
}
完整示例:
import pandas as pd
d = {
'application/png': '.png',
'image/gif': '.gif',
'image/jpeg': '.jpg',
'image/jpg': '.jpg',
'image/pjpeg': '.jpg',
'image/png': '.png',
'image/x-png': '.png',
}
# some random data
df = pd.DataFrame({
'id': ['1232131iujajga','21hi3hk123h21', '1231231231'],
'content_type': ['image/gif', 'image/jpg', '']
})
df['name'] = df['id'] + df['content_type'].map(d).fillna('')
print(df)
返回:
content_type id name
0 image/gif 1232131iujajga 1232131iujajga.gif
1 image/jpg 21hi3hk123h21 21hi3hk123h21.jpg
2 1231231231 1231231231