Pandas:如果包含子字符串,则替换列中的某些值

时间:2016-10-24 09:00:45

标签: python pandas

我有数据框

member_id,device_type,device_id,event_type,event_path,event_duration
603609,url,mail.ru/,0,pc,7d4a095373874b4fb26a2e6d070b6ad3
603609,url,mail.ru/,0,pc,7d4a095373874b4fb26a2e6d070b6ad3
603609,url,mail.ru/,0,pc,7d4a095373874b4fb26a2e6d070b6ad3
603609,url,mail.ru/,3,pc,7d4a095373874b4fb26a2e6d070b6ad3
603609,url,mail.ru/community.livejournal.com/psp_ru,28,pc,7d4a095373874b4fb26a2e6d070b6ad3
603609,url,lady.mail.ru/article/491411-kurban-omarov-otvetil-na-obvinenija-ksenii-borodinoj/?from=mr_news,0,pc,7d4a095373874b4fb26a2e6d070b6ad3
603609,url,mail.ru/,0,pc,7d4a095373874b4fb26a2e6d070b6ad3
603609,url,lady.mail.ru/article/491411-kurban-omarov-otvetil-na-obvinenija-ksenii-borodinoj/?from=mr_news,0,pc,7d4a095373874b4fb26a2e6d070b6ad3
603609,url,lady.mail.ru/article/491411-kurban-omarov-otvetil-na-obvinenija-ksenii-borodinoj/?from=mr_news,0,pc,7d4a095373874b4fb26a2e6d070b6ad3

我应该从另一个文件中找到子字符串,如果它包含pattrn,请从category

创建一个列find.xlsx
url category    category2
falloutsite.ru/ Рубрики/Hi-Tech/Программы/Софт/Игры/    Рубрики/Hi-Tech/Программы/Софт/Игры/ 
kmzpub.ru/games.asp Рубрики/Hi-Tech/Программы/Софт/Игры/Универсальное/  Рубрики/Hi-Tech/Программы/Софт/Игры/Универсальное/ 
sigma-team.ru/content/view/15/19    Рубрики/Hi-Tech/Программы/Софт/Игры/Quake и Counter-Strike/     Рубрики/Hi-Tech/Программы/Софт/Игры/Quake и Counter-Strike/ 
community.livejournal.com/psp_ru    Рубрики/Развлечения/Игры/Приставочные игры/     Рубрики/Развлечения/Игры/Приставочные игры/ 

我用

df = pd.read_csv('car owners games_category.csv')
find = pd.read_excel('blue.xlsx')
d = find.set_index('url')['category'].to_dict()
df['category'] = df.device_id.apply(lambda x: pd.Series([v for k,v in d.items() if k in x]))

将其替换为类别,但返回ValueError: Wrong number of items passed 2, placement implies 1。 我尝试使用mapisin,但它需要常见的字符串。

1 个答案:

答案 0 :(得分:1)

经过长时间的真实数据测试后,列表推导返回2类别存在问题Series,而不是行13中的问题。

一个可行的解决方案是使用iloc[0]仅返回Series中的第一项:

df['category'] = df.device_id
                   .apply(lambda x: pd.Series([v for k,v in d.items() if k in x]).iloc[0])

另一种解决方案是按drop删除此行:

find.drop(13, inplace=True)

测试所有有问题的行:

#custom function return list to column 'category'
def f(x):
    return [v for k,v in d.items() if k in x]
df['category'] = df.device_id.apply(f)
print (df)

#filter all rows where length of list is not 1
print (df[df.category.apply(len) != 1])

#return length of problematic rows
print (df.ix[df.category.apply(len) != 1, 'category'].apply(len))