Pandas выбрать строки, сумма которых наиболее близка к заданному числу - PullRequest
1 голос
/ 09 июля 2020

Я прочитал таблицу Википедии в фрейм данных:

https://es.wikipedia.org/wiki/Anexo: Municipios_de_la_Comunidad_de_Madrid

import pandas as pd
from unicodedata import normalize

df = pd.read_html('https://es.wikipedia.org/wiki/Anexo:Municipios_de_la_Comunidad_de_Madrid')
madrid = df[0] 
madrid['Población(2017)'] = madrid['Población(2017)'].apply(lambda x:normalize('NFKD', x)).str.replace(' ','')
madrid['Población(2017)'] = pd.to_numeric(madrid['Población(2017)'])

Мне пришлось unicodedata.normalize, потому что очевидные пробелы для числа форматирования, такие как 206 589, на самом деле были символом xa0

Теперь я хочу выбрать из этого фрейма данных подмножество городов, население которых прибавляет общее число как можно ближе к заданному числу. Я хотел бы выбрать, население каких городов, вместе взятых, будет чуть больше 2200000 жителей

Я пробовал варианты этого без результата

madrid[madrid['Población(2017)'].sum() > 2178000]

сообщение об ошибке:

KeyError                                  Traceback (most recent call last)
/usr/local/lib/python3.6/dist-packages/pandas/core/indexes/base.py in get_loc(self, key, method, tolerance)
   2645             try:
-> 2646                 return self._engine.get_loc(key)
   2647             except KeyError:

pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()

pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()

pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item()

pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item()

KeyError: True

Может ли кто-нибудь определить условие, которое выбирает то, что я хочу?

Заранее спасибо

Ответы [ 2 ]

1 голос
/ 09 июля 2020

Это могло быть возможным решением без использования какой-либо комбинации. Пожалуйста, проверьте это и дайте мне знать.

new_val = 2178000
target = 2178000
col = 'Población(2017)'
indexx = []
out_val = 0
df = pd.read_html('https://es.wikipedia.org/wiki/Anexo:Municipios_de_la_Comunidad_de_Madrid')
x = df[0]
x["Población(2017)"] = pd.to_numeric(x["Población(2017)"].str.replace("[\xa0]","", regex=True))
while target > out_val:
    x['diff_to_n'] = (x[col] - new_val)
    s =  x.where(x['diff_to_n'] == x['diff_to_n'].min())
    ind = s[col].idxmax()
    x.drop(ind, inplace=True)
    indexx.append(ind)
    out_val += s[col].max()
    new_val = new_val - s[col].max()
new_df = pd.read_html('https://es.wikipedia.org/wiki/Anexo:Municipios_de_la_Comunidad_de_Madrid')
final = new_df[0].iloc[indexx]
final

Здесь out_val - это сумма, наиболее близкая к заданному вами значению. x - ваш фрейм данных, target и new_val - ваше заданное значение. Col - это ваши столбцы, которые вы хотите использовать. Я знаю, что это не изящное решение, но все же это решение. Final - это результат DataFrame.

this is list of index I got for your n = 2178000
this is the value I got which is closest to n = 2194486.0
1 голос
/ 09 июля 2020
  1. исключить Мадрид, поскольку он составляет> 2,2 млн.
  2. отсортировать по численности населения по убыванию (для получения минимального набора), вычислить cumsum ()
  3. муниципалитет ios являются затем установите, где кумулятивная сумма составляет <2.2M </li>
  4. отфильтруйте исходный фрейм данных по индексам, указанным в 3

Чтобы сгенерировать другие варианты, исключите другой муниципальный ios или используйте другой вид

import lxml
import pandas as pd
df = pd.read_html('https://es.wikipedia.org/wiki/Anexo:Municipios_de_la_Comunidad_de_Madrid')
dfm = df[0]
dfm["Población(2017)"] = pd.to_numeric(dfm["Población(2017)"].str.replace("[\xa0]","", regex=True))
exc = ["Madrid","Alcalá de Henares","Móstoles"]
dfl = dfm[~dfm["Nombre"].isin(exc)].sort_values("Población(2017)", ascending=False).cumsum()
dfm[dfm.index.isin(dfl[dfl["Población(2017)"]<2200000].index)] #.sort_values("Población(2017)", ascending=False)

выход

Nombre  Población(2017) Superficie (km²)[1]​    Mapa    Escudo  Capitalidad[1]​ Altitud(msnm)[a]​[2]​
4   Alcalá de Henares   194310  8772    NaN NaN Alcalá de Henares   587
5   Alcobendas  114864  4498    NaN NaN Alcobendas  669
6   Alcorcón    168141  3373    NaN NaN Alcorcón    711
12  Aranjuez    58213   20111   NaN NaN Aranjuez    495
44  Collado Villalba    62152   2652    NaN NaN Collado Villalba    918
50  Coslada 83011   1201    NaN NaN Coslada 620
57  Fuenlabrada 194669  3941    NaN NaN Fuenlabrada 662
64  Getafe  178288  7838    NaN NaN Getafe  622
73  Leganés 187720  4309    NaN NaN Leganés 667
79  Majadahonda 71299   3847    NaN NaN Majadahonda 740
90  Móstoles    206589  4536    NaN NaN Móstoles    660
101 Parla   125898  2451    NaN NaN Parla   646
110 Pozuelo de Alarcón  85605   4320    NaN NaN Pozuelo de Alarcón  689
119 Rivas-Vaciamadrid   83767   6738    NaN NaN Vaciamadrid 563
123 Las Rozas de Madrid 95071   5831    NaN NaN Las Rozas de Madrid 712
130 San Sebastián de los Reyes  86707   5866    NaN NaN San Sebastián de los Reyes  672
142 Torrejón de Ardoz   128013  841 NaN NaN Torrejón de Ardoz   586
156 Valdemoro   73976   6417    NaN NaN Valdemoro   613

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...