代码之家  ›  专栏  ›  技术社区  ›  Mohammad Zain Abbas

基于条件更改数据帧行值的更快方法

  •  3
  • Mohammad Zain Abbas  · 技术社区  · 6 年前

    我有一个 包含 数百万张唱片 ,


    data set


    我在代码中使用的列表是 ,

    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 名称 获取价值 属于 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
    

    输出

    output

    问题是,它需要相当长的时间,因为数据帧相当大。

    2 回复  |  直到 6 年前
        1
  •  1
  •   jpp    6 年前

    使用字典和 按列 操作:

    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

        2
  •  1
  •   Anton vBR    6 年前

    我会将你的列表重组为字典,并使用地图:

    df['name'] = df['id'] + df['content_type'].map(d).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