[英]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_md和dr_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...
並做出以下假設:
我創建了以下函數來解析列表:
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.