Заполните значения NA в DataFrame Pandas, используя другой DataFrame Pandas - PullRequest
0 голосов
/ 27 октября 2018
import pandas as pd


df1 = pd.DataFrame({
                  'value1': ["a","a","a","b","b","b","c","c"],
                  'value2': [1,2,3,4,4,4,5,5],
                    'value3': [1,2,3, None , None, None, None, None],
                    'value4': [1,2,3,None , None, None, None, None],
                    'value5': [1,2,3,None , None, None, None, None]})

df2 = pd.DataFrame({
                  'value1': ["k","j","l","m","x","y"],
                  'value2': [2, 2, 1, 3, 4, 5],
                  'value3': [2, 2, 2, 3, 4, 5],
                  'value4': [3, 2, 2, 3, 4, 5],
                  'value5': [2, 1, 2, 3, 4, 5]})

df1 = 
  value1  value2  value3  value4  value5
0      a       1     1.0     1.0     1.0
1      a       2     2.0     2.0     2.0
2      a       3     3.0     3.0     3.0
3      b       4     NaN     NaN     NaN
4      b       4     NaN     NaN     NaN
5      b       4     NaN     NaN     NaN
6      c       5     NaN     NaN     NaN
7      c       5     NaN     NaN     NaN

df2 = 
  value1  value2  value3  value4  value5
0      k       2       2       3       2
1      j       2       2       2       1
2      l       1       2       2       2
3      m       3       3       3       3
4      x       4       4       4       4
5      y       5       5       5       5

Я хотел бы заполнить NaN в df1 из значений в df2

Так что результаты df1 будут выглядеть так:

df1 = 
  value1  value2  value3  value4  value5
0      a       1     1.0     1.0     1.0
1      a       2     2.0     2.0     2.0
2      a       3     3.0     3.0     3.0
3      b       4     2       2       1
4      b       4     2       2       2
5      b       4     3       3       3
6      c       5     4       4       4
7      c       5     5       5       5

Я использовал следующие коды.

tmp1 = df1[df1.value1 == 'b'].iloc[:, 2:]
tmp2 = df2.iloc[1:, 2:]

tmp1 = tmp2 может обновлять значения в tmp1, но когда я использую следующее

df1[df1.value1 == 'b'].iloc[:, 2:]= tmp2

Он не обновляет значения в df1, как показано ниже.

  value1  value2  value3  value4  value5
0      a       1     1.0     1.0     1.0
1      a       2     2.0     2.0     2.0
2      a       3     3.0     3.0     3.0
3      b       4     NaN     NaN     NaN
4      b       4     NaN     NaN     NaN
5      b       4     NaN     NaN     NaN
6      c       5     NaN     NaN     NaN
7      c       5     NaN     NaN     NaN

Почему это происходит и как я могу решить эту проблему?

Спасибо.

Ответы [ 2 ]

0 голосов
/ 27 октября 2018

Если вы хотите заменить значения nan с помощью выравнивания индекса, используйте pandas fillna

df1.fillna(df2)

Добавьте на место, если вы хотите обновить df1

df1.fillna(df2, inplace=True)

-

  • редактировать для случая без выровненных индексов:

Если индексы целевых и замещающих значений не выровнены, их можно выровнять, чтобы можно было использовать метод заполнения кадра данных.

Чтобы выровнять индексы, получите индексы строк, содержащих nans в df1, которые нужно заменить, отфильтруйте df2, чтобы включить значения замены, а затем назначьте индексы замены из df1 в качестве индекса df2.Затем используйте fillna для переноса значений из df2 в df1.

# in this case, find index values when df1.value1 is greater than or equal to 'b'
# (alternately could be indexes of rows containing nans)
idx = df1.index[df1.value1 >= 'b']
# get the section of df2 which will provide replacement values
# limit length to length of idx
align_df = df2[1:len(idx) + 1]
# set the index to match the nan rows from df1
align_df.index = idx
# use auto-alignment with fillna to transfer values from align_df(df2) to df1
df1.fillna(align_df)

# or can use df1.combine_first(align_df) because of the matching target and replacement indexes
0 голосов
/ 27 октября 2018

Эта строка не делает то, что, по вашему мнению, делает:

tmp1 = df1[df1.value1 == 'b'].iloc[:, 2:]

Методы применяются последовательно , поэтому df1[df1.value1 == 'b'] сохраняет только строки 3, 4, 5 из df1. Но это не то, что вы хотите, вы хотите обновить все строки, начиная с первого экземпляра ваше условие выполнено.

Вместо этого сначала найдите нужный индекс.

idx = df1['value1'].eq('b').values.argmax()

Затем вам нужно явно назначить последние n строк из df2:

df1.iloc[idx:, 2:] = df2.iloc[-(len(df1.index)-idx):, 2:].values

print(df1)

  value1  value2  value3  value4  value5
0      a       1     1.0     1.0     1.0
1      a       2     2.0     2.0     2.0
2      a       3     3.0     3.0     3.0
3      b       4     2.0     2.0     1.0
4      b       4     2.0     2.0     2.0
5      b       4     3.0     3.0     3.0
6      c       5     4.0     4.0     4.0
7      c       5     5.0     5.0     5.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...