繁体   English   中英

熊猫数据框:选择列中的列表项,然后在项目上转换字符串

[英]Pandas dataframe: select list items in a column, then transform string on the items

我要导入到我的数据框中的一列是一个列表。 我需要从所述列表中选择某些值,转换该值并将其添加到数据框中的两个新列之一。 前:

姓名 Listed_Items
汤姆 [“dr_md_coca_cola”、“dr_od_water”、“土豆”、“草”、“ot_other_stuff”]
史蒂夫 [“dr_od_orange_juice”、“土豆”、“草”、“ot_other_stuff”、“dr_md_pepsi”]
菲尔 [“dr_md_dr_pepper”、“土豆”、“草”、“dr_od_coffee”、“ot_other_stuff”]

根据我的阅读,我可以将该列变成一个列表

df["listed_items"] = df["listed_items"].apply(eval)

但是我看不到如何找到任何以dr_md 开头的列表项,提取该项目,删除起始 dr_md 替换任何下划线,将第一个字母大写并将其添加到行中的新MD列中。 然后对dr_od再次进行同样的操作。 列表中只有一项在每一行中以dr_mddr_od开头。 期望的输出

姓名 医学博士 外径
汤姆 可口可乐
史蒂夫 百事可乐 橙汁
菲尔 胡椒博士 咖啡

使用pivot_table

df = df.explode('Listed_Items')
df = df[df.Listed_Items.str.contains('dr_')]

df['Type'] = df['Listed_Items'].str.contains('dr_md').map({True: 'MD', 
                                                           False: 'OD'})

df.pivot_table(values='Listed_Items', 
               columns='Type', 
               index='Name',
               aggfunc='first')

Type                MD                  OD
Name                                      
Phil   dr_md_dr_pepper        dr_od_coffee
Steve      dr_md_pepsi  dr_od_orange_juice
Tom    dr_md_coca_cola         dr_od_water

从这里开始,只需按照您的意愿美化您的数据集。

您需要做的是创建一个为您执行处理的函数,您可以将其传递给apply (或在本例中为map )。 或者,您可以将列表列扩展为多个列,然后再处理它们,但这仅在您的列表始终处于相同顺序时才有效(请参阅panda expand columns with list into multiple columns )。 因为您只有一个输入列,所以您可以使用map而不是apply

def process_dr_md(l:list):
    for s in l:
        if s.startswith("dr_md_"):
            # You can process your string further here
            return l[6:]

def process_dr_od(l:list):
    for s in l:
        if s.startswith("dr_od_"):
            # You can process your string further here
            return l[6:]

df["listed_items"] = df["listed_items"].map(eval)
df["MD"] = df["listed_items"].map(process_dr_md)
df["OD"] = df["listed_items"].map(process_dr_od)

我希望这能让你上路!

我采取了与以前的答案略有不同的方法。 给定一个 df 形式:

    Name    Items
0   Tom [dr_md_coca_cola, dr_od_water, potatoes, grass...
1   Steve   [dr_od_orange_juice, potatoes, grass, ot_other...
2   Phil    [dr_md_dr_pepper, potatoes, grass, dr_od_coffe...  

并做出以下假设:

  1. 列表中只有一项与目标掩码匹配
  2. 目标掩码始终出现在输入字符串的开头

我创建了以下函数来解析列表:

import re
def parse_Items(tgt_mask: str, itmList: list) -> str:
    p = re.compile(tgt_mask)
    for itm in itmList:
        if p.match(itm):
            return itm[p.search(itm).span()[1]:].replace('_', ' ')  

然后,您可以使用以下内容修改原始数据场:

df['MD'] = [parse_Items('dr_md_', x) for x in df['Items'].to_list()]
df['OD'] = [parse_Items('dr_od_', x) for x in df['Items'].to_list()]
df.pop('Items')  

这会产生以下结果:

    Name    MD          OD
0   Tom     coca cola   water
1   Steve   pepsi       orange juice
2   Phil    dr pepper   coffee

我会在放入数据框之前对数据进行规范化:

import pandas as pd
from typing import Dict, List, Tuple


def clean_stuff(text: str):
    clean_text = text[6:].replace('_', ' ')
    return " ".join([
        word.capitalize()
        for word in clean_text.split(" ")
    ])


def get_md_od(stuffs: List[str]) -> Tuple[str, str]:
    md_od = [s for s in stuffs if s.startswith(('dr_md', 'dr_od'))]
    md_od = sorted(md_od)
    print(md_od)

    return clean_stuff(md_od[0]), clean_stuff(md_od[1])


dirty_stuffs = [{'Name': 'Tom',
                 'Listed_Items': ["dr_md_coca_cola",
                                  "dr_od_water",
                                  "potatoes",
                                  "grass",
                                  "ot_other_stuff"]},
                {'Name': 'Tom',
                 'Listed_Items': ["dr_md_coca_cola",
                                  "dr_od_water",
                                  "potatoes",
                                  "grass",
                                  "ot_other_stuff"]}
                ]

normalized_stuff: List[Dict[str, str]] = []
for stuff in dirty_stuffs:
    md, od = get_md_od(stuff['Listed_Items'])
    normalized_stuff.append({
        'Name': stuff['Name'],
        'MD': md,
        'OD': od,
    })

df = pd.DataFrame(normalized_stuff)
print(df)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM