Как избежать KeyError в dataframe - PullRequest
0 голосов
/ 14 ноября 2018

Я проверяю свой фрейм данных с кодом ниже,

df = df[(df[['name', 'issuer_id', 'service_area_id']].notnull().all(axis=1)) &
                ((df['plan_year'].notnull()) & (df['plan_year'].astype(str).str.isdigit()) & (df['plan_year'].astype(str).str.len() == 4)) &
                (df[['network_url', 'formulary_url', 'sbc_download_url', 'treatment_cost_calculator_url']].astype(str).apply(lambda x: (x.str.contains('\A(https?:\/\/)([a-zA-Z0-9\-_])*(\.)*([a-zA-Z0-9\-]+)\.([a-zA-Z\.]{2,5})(\.*.*)?\Z')) | x.isin(['nan'])).all(axis=1)) &
                (df[['promotional_label']].astype(str).apply(lambda x: (x.str.len <= 65) | x.isin(['nan'])).all(axis=1)) &
                # (df[['sort_rank_override']].astype(str).apply(lambda x: (x.str.isdigit()) | x.isin(['nan'])).all(axis=1)) &
                ((df['hios_plan_identifier'].notnull()) & (df['hios_plan_identifier'].str.len() >= 10) & (df['hios_plan_identifier'].str.contains('\A(\d{5}[A-Z]{2}[a-zA-Z0-9]{3,7}-TMP|\d{5}[A-Z]{2}\d{3,7}(\-?\d{2})*)\Z'))) &
                (df['type'].isin(['MetalPlan', 'MedicarePlan', 'BasicHealthPlan', 'DualPlan', 'MedicaidPlan', 'ChipPlan'])) &
                (df['price_period'].isin(['Monthly', 'Yearly'])) &
                (df['is_age_29_plan'].astype(str).isin(['True', 'False', 'nan']))]
                # (df[['composite_rating']].astype(str).apply(lambda x: (x.str.isin(['True', 'False']) & x.isnotin(['nan'])).all(axis=1)))]

Это бросило бы меня

KeyError: "['name'] нет в индексе"

когда столбец отсутствует в моем фрейме данных. Мне нужно обрабатывать все столбцы. Как я могу эффективно добавить проверку в мой код выше, который проверяет проверку только при наличии столбца?

Ответы [ 2 ]

0 голосов
/ 14 ноября 2018

Добавьте еще одну переменную с именем columns и отфильтруйте ее с теми, которые существуют в df:

columns = ['name', 'issuer_id', 'service_area_id']
existing = [i for i in columns if i in df.columns]
df = df[(df[existing]...

EDIT Вы также можете назначить каждое условие переменной и использовать его позже так:

cond1 = df['is_age_29_plan'].astype(str).isin(['True', 'False', 'nan']) if 'is_age_29_plan' in df.columns else True

Затем используйте cond1 в своем выражении фильтрации.

0 голосов
/ 14 ноября 2018

Вы можете использовать intersection:

L = ['name', 'issuer_id', 'service_area_id']
cols = df.columns.intersection(L)

(df[cols].notnull().all(axis=1))

EDIT:

df = pd.DataFrame({
        'name':list('abcdef'),
         'plan_year':[2015,2015,2015,5,5,4],
})
print (df)
  name  plan_year
0    a       2015
1    b       2015
2    c       2015
3    d          5
4    e          5
5    f          4

Идея состоит в том, чтобы сначала создать словарь допустимых значений для каждого столбца:

valid = {'name':'a', 
        'issuer_id':'a',
        'service_area_id':'a',
        'plan_year':2015,
         ...}

Затем отфильтруйте новый словарь по отсутствующим столбцам и assign до исходного DataFrame и создайте новый фрейм данных:

d1 = {k: v for k, v in valid.items() if k in set(valid.keys()) - set(df.columns)}
print (d1)
{'issuer_id': 'a', 'service_area_id': 'a'}


df1 = df.assign(**d1)
print (df1)
  name  plan_year issuer_id service_area_id
0    a       2015         a               a
1    b       2015         a               a
2    c       2015         a               a
3    d          5         a               a
4    e          5         a               a
5    f          4         a               a

Последний фильтр:

m1 = (df1[['name', 'issuer_id', 'service_area_id']].notnull().all(axis=1)) 
m2 = ((df1['plan_year'].notnull()) & 
      (df1['plan_year'].astype(str).str.isdigit()) & 
      (df1['plan_year'].astype(str).str.len() == 4))

df1 = df1[m1 & m2]
print (df1)
  name  plan_year issuer_id service_area_id
0    a       2015         a               a
1    b       2015         a               a
2    c       2015         a               a

Последнее, что вы можете удалить вспомогательные столбцы:

df1 = df1[m1 & m2].drop(d1.keys(), axis=1)
print (df1)
  name  plan_year
0    a       2015
1    b       2015
2    c       2015
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...