У меня есть фрейм данных с двумя уровнями столбцов, который выглядит так:

Я использую цикл для построения диаграмм для каждой страны
import requests
import pandas as pd
import json
from pandas import read_html
from pandas.io.json import json_normalize
import urllib2, json
import html5lib
import statsmodels.api as sm
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
for country in WHOData.columns: # Iterate over countries
country_df = WHOData[[country]].unstack().fillna(0) #; Unstack deaths and rates
cases = country_df.iloc[:, country_df.columns.get_level_values(1)=='Cases']
rate = country_df.iloc[:, country_df.columns.get_level_values(1)=='Rate']
x = np.array(rate)
y = np.array(cases)
plt.scatter(x,y)
results = sm.OLS(y,sm.add_constant(x)).fit()
plt.plot(x, results.fittedvalues)
color = 'red'
plt.ylabel('Measles Cases', color=color)
color = 'blue'
plt.xlabel('Vaccination Rate', color=color)
plt.title(country)
plt.show()
Я хочу удалить все строки, которые имеют 0 либо в случаях, либо в рейтинге.
Я попробовал этот фрагмент кода (с печатью df вместо построения диаграммы, чтобы показать мне, что происходит)
for country in WHOData.columns: # Iterate over countries
country_df = WHOData[[country]].unstack(); # Unstack deaths and rates
country_df = country_df.drop((country_df.iloc[:, country_df.columns.get_level_values(1)=='Rate']==0)|(country_df.iloc[:, country_df.columns.get_level_values(1)=='Cases']==0))
print country_df
break
И я получил такую ошибку:
ValueError: labels [(u'Afghanistan', 'Cases') (u'Afghanistan', 'Rate')] not contained in axis
Что на самом деле заставляет меня чувствовать, что я близок, но также ставит меня в тупик
Любая помощь с благодарностью оценена
вот код для создания этого фрейма данных:
df = pd.DataFrame({(u'Afghanistan', 'Cases'): {1980: 32455.0,
1981: 31107.0,
1982: 20320.0,
1983: 18808.0,
1984: 16199.0,
1985: 14457.0},
(u'Afghanistan', 'Pop'): {1980: 13211000.0,
1981: 12894800.0,
1982: 12578600.0,
1983: 12262400.0,
1984: 11946200.0,
1985: 11630000.0},
(u'Afghanistan', 'Rate'): {1980: 11.0,
1981: 0.0,
1982: 8.0,
1983: 9.0,
1984: 14.0,
1985: 14.0},
(u'Albania', 'Cases'): {1980: 0.0,
1981: 0.0,
1982: 3.0,
1983: 17.0,
1984: 0.0,
1985: 0.0},
(u'Albania', 'Pop'): {1980: 2681000.0,
1981: 2738200.0,
1982: 2795400.0,
1983: 2852600.0,
1984: 2909800.0,
1985: 2967000.0},
(u'Albania', 'Rate'): {1980: 90.0,
1981: 90.0,
1982: 93.0,
1983: 96.0,
1984: 96.0,
1985: 96.0},
(u'Algeria', 'Cases'): {1980: 15527.0,
1981: 20849.0,
1982: 29584.0,
1983: 22126.0,
1984: 22553.0,
1985: 20114.0},
(u'Algeria', 'Pop'): {1980: 19338000.0,
1981: 19983600.0,
1982: 20629200.0,
1983: 21274800.0,
1984: 21920400.0,
1985: 22566000.0},
(u'Algeria', 'Rate'): {1980: 0.0,
1981: 0.0,
1982: 0.0,
1983: 0.0,
1984: 0.0,
1985: 68.0},
(u'Andorra', 'Cases'): {1980: 0.0,
1981: 0.0,
1982: 0.0,
1983: 0.0,
1984: 0.0,
1985: 0.0},
(u'Andorra', 'Pop'): {1980: 36000.0,
1981: 37800.0,
1982: 39600.0,
1983: 41400.0,
1984: 43200.0,
1985: 45000.0},
(u'Andorra', 'Rate'): {1980: 0.0,
1981: 0.0,
1982: 0.0,
1983: 0.0,
1984: 0.0,
1985: 0.0},
(u'Angola', 'Cases'): {1980: 29656.0,
1981: 19714.0,
1982: 30067.0,
1983: 22589.0,
1984: 22685.0,
1985: 22822.0},
(u'Angola', 'Pop'): {1980: 8212000.0,
1981: 8518600.0,
1982: 8825200.0,
1983: 9131800.0,
1984: 9438400.0,
1985: 9745000.0},
(u'Angola', 'Rate'): {1980: 0.0,
1981: 0.0,
1982: 0.0,
1983: 26.0,
1984: 35.0,
1985: 44.0}})
вот код, который я ДЕЙСТВИТЕЛЬНО запустил - он был для гораздо большего фрейма данных - примерно 200 стран:
df=WHOData.unstack().fillna(0)
for country in df.columns.get_level_values(0).unique():
country_df = df[[c for c in df.columns if c[0] == country]]
for c in [c for c in country_df.columns if c[1] in ['Cases', 'Rate']]:
country_df = country_df[country_df[c] > 0]
cases = country_df.iloc[:, country_df.columns.get_level_values(1)=='Cases']
rate = country_df.iloc[:, country_df.columns.get_level_values(1)=='Rate']
x = np.array(rate)
y = np.array(cases)
plt.scatter(x,y)
results = sm.OLS(y,sm.add_constant(x)).fit()
plt.plot(x, results.fittedvalues)
color = 'red'
plt.ylabel('Measles Cases', color=color)
color = 'blue'
plt.xlabel('Vaccination Rate', color=color)
plt.title(country)
plt.show()






Вы можете перебирать страны. Для каждой страны перебирайте столбцы как кортежи, а для тех, у которых второе значение - Cases или Rate, опускайте соответствующие строки:
for country in df.columns.get_level_values(0).unique():
country_df = df[[c for c in df.columns if c[0] == country]]
for c in [c for c in country_df.columns if c[1] in ['Cases', 'Rate']]:
country_df = country_df[country_df[c] > 0]
print(country_df)
Это дает следующий результат:
Afghanistan
Cases Pop Rate
1980 32455.0 13211000.0 11.0
1982 20320.0 12578600.0 8.0
1983 18808.0 12262400.0 9.0
1984 16199.0 11946200.0 14.0
1985 14457.0 11630000.0 14.0
Albania
Cases Pop Rate
1982 3.0 2795400.0 93.0
1983 17.0 2852600.0 96.0
Algeria
Cases Pop Rate
1985 20114.0 22566000.0 68.0
Empty DataFrame
Columns: [(Andorra, Cases), (Andorra, Pop), (Andorra, Rate)]
Index: []
Angola
Cases Pop Rate
1983 22589.0 9131800.0 26.0
1984 22685.0 9438400.0 35.0
1985 22822.0 9745000.0 44.0
@kiltannen Я добавил распечатку вывода. Глядя на вашу редакцию, я думаю, вы по какой-то причине удалили мой print и добавили break, поэтому он повторяется только для одной страны.
ОК - ТАК, я напортачил, используя WHOData, не подготовив их должным образом. Как только я правильно запустил unstack, он заработал ИДЕАЛЬНО !. БОЛЬШОЕ СПАСИБО, Ами!
Я прогнал на нем свои графики - и они выглядят намного понятнее с выпавшими значениями "0". Теперь они показывают четкую взаимосвязь между двумя наборами данных для каждой страны - там, где раньше цифры «0» омрачали диаграмму взаимосвязи.
@kiltannen Очень хороший пример очистки данных.
Я думаю, что МОЖЕТ начать разбираться в некоторых из более простых подходов к Data Wrangling. Мне еще предстоит пройти долгий путь, но некоторые ответы, которые я здесь вижу, начинают обретать для меня смысл, а не просто представляют собой полные загадки.
Спасибо, Ами, я попробовал это и в результате получил полностью пустой фреймворк. Я отредактировал вопрос выше, что я сделал ...