Страницы

Поиск по вопросам

пятница, 3 января 2020 г.

Разбить dataframe по условию

#python #pandas #dataframe


У меня есть датафрейм, состоящий из двух столбцов. в первос записаны емейлы пользователей,а
во втором - страны проживания. Мне нужно выбрать из первого те значения, которе содержат
gmail.com или hotmail.com. А потом построить график "отношение количества gmail.com
и hotmail.com в соответствии со страной."
В чем ошибка?

import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
df = pd.read_csv("/home/ann/df(1).csv", sep=';')
gmail_list = []
hotmail_list = []

for i in df[['email', 'country_code']]:
    if "@gmail.com" in i:
      gmail_list.append(df.loc[:,'country_code'])
    elif "@hotmail.com" in i:
      hotmail_list.append(country_code)


график


    


Ответы

Ответ 1



В Pandas данную задачу можно решить однострочным (one-liner) выражением: import pandas as pd import matplotlib.pyplot as plt import matplotlib matplotlib.style.use('ggplot') df = pd.read_csv(r'D:\download\df(1).csv', sep=';') (df.assign(domain=df['email'].str.extract(r'@(.*)', expand=False)) .query("domain in ['gmail.com','hotmail.com']") .groupby(['country_code','domain']) .count()['email'] .unstack('domain', fill_value=0) .plot.bar(rot=0, stacked=True)) plt.show() Результат: В процентах: (df.assign(domain=df['email'].str.extract(r'@(.*)', expand=False)) # extract domain from email .query("domain in ['gmail.com','hotmail.com']") # filter domains .groupby('country_code')['domain'] # group by `country_code` .value_counts(normalize=True) # and count unique values per group (normalize: relative frequency) .mul(100) # convert factor to percentage .unstack('domain', fill_value=0) # pivot: transform long to wide .plot.bar(rot=0, stacked=True, figsize=(12,8))) ) Результат: Как это работает? Сначала надо вычленить домен из email: In [113]: df.assign(domain=df['email'].str.extract(r'@(.*)', expand=False)) Out[113]: email country_code domain 0 12345kinglobito94@hotmail.com RU hotmail.com 1 12345arturdyikan6211@gmail.com RU gmail.com 2 12345leonardosebastianld.20@gmail.com PE gmail.com 3 12345k23156876vs@hotmail.com RU hotmail.com 4 12345jhuillcag@hotmail.com PE hotmail.com .. ... ... ... 995 nilton223009@hotmail.com PE hotmail.com 996 xasbkar@gmail.com RU gmail.com 997 kl@gmail.com RU gmail.com 998 emerson-carauna@hotmail.com BR hotmail.com 999 shamkhalaevamir@gmail.com RU gmail.com [1000 rows x 3 columns] потом отфильтровать, чтобы остались только gmail.com и hotmail.com: In [114]: (df.assign(domain=df['email'].str.extract(r'@(.*)', expand=False)) ...: .query("domain in ['gmail.com','hotmail.com']")) ...: Out[114]: email country_code domain 0 12345kinglobito94@hotmail.com RU hotmail.com 1 12345arturdyikan6211@gmail.com RU gmail.com 2 12345leonardosebastianld.20@gmail.com PE gmail.com 3 12345k23156876vs@hotmail.com RU hotmail.com 4 12345jhuillcag@hotmail.com PE hotmail.com .. ... ... ... 995 nilton223009@hotmail.com PE hotmail.com 996 xasbkar@gmail.com RU gmail.com 997 kl@gmail.com RU gmail.com 998 emerson-carauna@hotmail.com BR hotmail.com 999 shamkhalaevamir@gmail.com RU gmail.com [954 rows x 3 columns] считаем количество различных доменов для каждой страны: In [115]: (df.assign(domain=df['email'].str.extract(r'@(.*)', expand=False)) ...: .query("domain in ['gmail.com','hotmail.com']") ...: .groupby('country_code')['domain'] ...: .value_counts(normalize=True) ...: ) Out[115]: country_code domain AR hotmail.com 0.750000 gmail.com 0.250000 BR hotmail.com 0.609375 gmail.com 0.390625 PE hotmail.com 0.702564 gmail.com 0.297436 RU gmail.com 0.956298 hotmail.com 0.043702 US gmail.com 0.900000 hotmail.com 0.100000 Name: domain, dtype: float64 делаем PIVOT: In [116]: (df.assign(domain=df['email'].str.extract(r'@(.*)', expand=False)) ...: .query("domain in ['gmail.com','hotmail.com']") ...: .groupby('country_code')['domain'] ...: .value_counts(normalize=True) ...: .mul(100) ...: .unstack('domain', fill_value=0) ...: ) Out[116]: domain gmail.com hotmail.com country_code AR 25.00000 75.00000 BR 39.06250 60.93750 PE 29.74359 70.25641 RU 95.62982 4.37018 US 90.00000 10.00000 рисуем график...

Комментариев нет:

Отправить комментарий