Есть ли способ заполнить пропущенные значения в нескольких столбцах, разделяя часть их имени значениями из другого столбца? - PullRequest
1 голос
/ 29 апреля 2019

Я пытаюсь заполнить NaN несколькими столбцами (слишком много для жесткого решения), которые разделяют часть своего имени со значениями из другого столбца в том же кадре данных pandas.

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

Например, рассмотрим фрейм данных:

df = pd.DataFrame({'Val': [1.2,5.4,3.1,4], 'Col - 1': [None,5,1,None], 'Col - 2': [None,None,6,None]})
print(df)

   Val  Col - 1  Col - 2
0  1.2      NaN      NaN
1  5.4      5.0      NaN
2  3.1      1.0      6.0
3  4.0      NaN      NaN

Заполнение нескольких столбцов постоянным значением работает:

df.loc[:,df.columns.str.contains('Col')] = df.loc[:,df.columns.str.contains('Col')].fillna(value=15)
print(df)

   Val  Col - 1  Col - 2
0  1.2     15.0     15.0
1  5.4      5.0     15.0
2  3.1      1.0      6.0
3  4.0     15.0     15.0

Заполнение одного столбца значениями из другого столбца также работает:

df['Col - 2'] = df['Col - 2'].fillna(value=df['Val'])
print(df)

   Val  Col - 1  Col - 2
0  1.2      NaN      1.2
1  5.4      5.0      5.4
2  3.1      1.0      6.0
3  4.0      NaN      4.0

То, что не работает, является комбинацией двух:

df.loc[:,df.columns.str.contains('Col')] = df.loc[:,df.columns.str.contains('Col')].fillna(value=df['Val'])

Выше ничего не делает и возвращает исходный кадр данных. То, что я ожидаю, это:

   Val  Col - 1  Col - 2
0  1.2      1.2      1.2
1  5.4      5.0      5.4
2  3.1      1.0      6.0
3  4.0      4.0      4.0

Ответы [ 3 ]

3 голосов
/ 29 апреля 2019

Вы должны добавить apply lambda, так как датафрейм fillna также проверит имя columns, вы заполните его pd.Series, который не соответствует columns, поэтому сделаете не удалось

df.loc[:,df.columns.str.contains('Col')].apply(lambda x : x.fillna(value=df['Val']))
2 голосов
/ 29 апреля 2019

Вы можете использовать df.filter() здесь:

m=df.filter(like='Col')
df[m.columns]=m.apply(lambda x: x.fillna(df.Val))
print(df)

   Val  Col - 1  Col - 2
0  1.2      1.2      1.2
1  5.4      5.0      5.4
2  3.1      1.0      6.0
3  4.0      4.0      4.0
1 голос
/ 29 апреля 2019

Вот способ обойти проблему с np.where:

cols = [col for col in df.columns if 'Col' in col]
df[cols] = np.where(df[cols].isna(), df.Val.values[:,None], df[cols])

Выход:

      Val    Col - 1    Col - 2
--  -----  ---------  ---------
 0    1.2        1.2        1.2
 1    5.4        5          5.4
 2    3.1        1          6
 3    4          4          4
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...