pandas - создать столбец true / false, если заголовок столбца является подстрокой другого столбца - PullRequest
1 голос
/ 01 апреля 2020

Я слежу за этим сообщением , чтобы создать количество столбцов, которые имеют значение true / false на основе наличия подстроки в другом столбце.

До использования кода, указанного выше пост, я смотрю на поле с именем LANGUAGES, которое имеет такие значения, как "ENG, SPA, CZE" или "ENG, SPA". К сожалению, данные представляют собой строку, разделенную запятыми, а не список, но без проблем, в одной строке я могу получить список из 25 уникальных значений.

Как только я получу список уникальных значений, я хочу создайте новый столбец для каждого значения, так что df[ENG], df[SPA], et c. колонны. Я хочу, чтобы эти столбцы имели значение true / false в зависимости от того, является ли заголовок подстрокой исходного столбца LANGUAGES.

После записи я использую df.apply(lambda x: language in df.LANGUAGES, axis = 1). Тем не менее, когда я проверяю значения столбцов (значение считается в последнем для l oop), все значения оказываются ложными.

Как создать столбец true / false на основе столбца заголовок является подстрокой другого столбца?

Мой код:

import json
import pandas as pd
import requests

url  = r"https://data.hud.gov/Housing_Counselor/search?AgencyName=&City=&State=&RowLimit=&Services=&Languages="

response = requests.get(url)

if response.status_code == 200:
    res = response.json()
    df = pd.DataFrame(res)
    df.columns = [str(h).upper() for h in list(df)]
    #
    # the below line is confusing but it creates a sorted list of all unique languages
    #
    languages = [str(s) for s in sorted(list(set((",".join(list(df["LANGUAGES"].unique()))).split(","))))]
    for language in languages:
        print(language)
        df[language] = df.apply(lambda x: language in df.LANGUAGES, axis = 1)
    for language in languages:
        print(df[language].value_counts())
        print("\n")
else:
    print("\nConnection was unsuccesful: {0}".format(response.status_code))

Редактировать: Был запрос на ввод необработанных данных и ожидаемый вывод. Вот как выглядит столбец:

+-------+-----------------+
| Index |    LANGUAGES    |
+-------+-----------------+
|     0 | 'ENG, OTH, RUS' |
|     1 | 'ENG'           |
|     2 | 'ENG, CZE, SPA' |
+-------+-----------------+

Это ожидаемый результат:

+-------+-----------------+------+-------+-------+-------+-------+
| Index |    LANGUAGES    | ENG  |  CZE  |  OTH  |  RUS  |  SPA  |
+-------+-----------------+------+-------+-------+-------+-------+
|     0 | 'ENG, OTH, RUS' | TRUE | FALSE | TRUE  | TRUE  | FALSE |
|     1 | 'ENG'           | TRUE | FALSE | FALSE | FALSE | FALSE |
|     2 | 'ENG, CZE, SPA' | TRUE | TRUE  | FALSE | TRUE  | FALSE |
+-------+-----------------+------+-------+-------+-------+-------+

Ответы [ 2 ]

1 голос
/ 01 апреля 2020

Два шага,

. Сначала мы разберем ваш список и создадим сводную таблицу для повторного согласования с вашим исходным df на основе индекса.

s  = df['LANGUAGES'].str.replace("'",'').str.split(',').explode().to_frame()

cols = s['LANGUAGES'].drop_duplicates(keep='first').tolist()

df2 = pd.concat([df, pd.crosstab(s.index, s["LANGUAGES"])[cols]], axis=1).replace(
    {1: True, 0: False}
)
print(df2)
         LANGUAGES   ENG    OTH    RUS    CZE    SPA
0  'ENG, OTH, RUS'  True   True   True  False  False
1            'ENG'  True  False  False  False  False
2  'ENG, CZE, SPA'  True  False  False   True   True
0 голосов
/ 01 апреля 2020

Нашел в в этом посте , я поменял следующую строку кода:

df[language] = df.apply(lambda x: language in df.LANGUAGES, axis = 1)

для следующих двух строк:

    criteria = lambda row : language in row["LANGUAGES"]
    df[language] = df.apply(criteria, axis =1)

И это работает .

import json
import pandas as pd
import requests

url  = r"https://data.hud.gov/Housing_Counselor/search?AgencyName=&City=&State=&RowLimit=&Services=&Languages="

response = requests.get(url)

if response.status_code == 200:
    res = response.json()
    df = pd.DataFrame(res)
    df.columns = [str(h).upper() for h in list(df)]
    #
    # the below line is confusing but it creates a sorted list of all unique languages
    #
    languages = [str(s) for s in sorted(list(set((",".join(list(df["LANGUAGES"].unique()))).split(","))))]
    for language in languages:
        criteria = lambda row : language in row["LANGUAGES"]
        df[language] = df.apply(criteria, axis =1)
    for language in languages:
        print(df[language].value_counts())
        print("\n")
else:
    print("\nConnection was unsuccesful: {0}".format(response.status_code))

Этот обмен строк также может работать:

for language in languages:
    df[language] = df.LANGUAGES.apply(lambda x: 'True' if language in x else 'False')
    print("{}:{}".format(language, df[df[language] == 'True'].shape[0]))
...