У меня есть датафрейм, состоящий из двух столбцов. в первос записаны емейлы пользователей,а во втором - страны проживания. Мне нужно выбрать из первого те значения, которе содержат 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)
график
Ответ
В 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
рисуем график...
Комментариев нет:
Отправить комментарий