объедините 2 столбца фрейма данных на основе условия

#python #python-3.x #pandas #dataframe

Вопрос:

Я создал фрейм данных

 data = [['Nan', 10], [4, 'Nan'], ['Nan', 12], ['Nan', 13], [5, 'Nan'], [6, 'Nan'], [7, 'Nan'], ['Nan', 8]]
df = pd.DataFrame(data, columns = ['min', 'max'])
print(df)
 

мой набор данных выглядит так,

 min    max
Nan    10
4      Max
Nan    12
Nan    13
5      Nan 
6      Nan
7      Nan
Nan    8
 

Я хочу создать новый столбец, который будет принимать одно значение от min, а затем одно значение от max. Если есть продолжение. 2 значения min/max (как мы видим, 12 и 13-это 2 значения) Я должен учитывать только одно значение (рассмотрим только 12, а затем перейдем к выбору min)

Короче говоря, в новом столбце должна быть одна строка минимального значения, затем одна строка максимального значения и так далее.

РЕЗУЛЬТАТ должен быть

 combined
10
4
12
5
8
 

Комментарии:

1. Могут ли быть два значения, отличные от nan, в одной строке?

2. нет, это невозможно

Ответ №1:

Вы можете попытаться изменить эти значения min и max с предыдущей строкой, чтобы не NaN NaN использовать .where() . Затем удалите строки с обоими min и max существом NaN . Затем обновите эти NaN значения min значением max в каждой строке, используя .combine_first() :

 df = df.replace('Nan', np.nan)

df['min'] = df['min'].where(df['min'].shift().isna())
df['max'] = df['max'].where(df['max'].shift().isna())
df = df.dropna(how='all')
df['combined'] = df['min'].combine_first(df['max'])
 

Результат:

 print(df)


   min   max  combined
0  NaN  10.0      10.0
1  4.0   NaN       4.0
2  NaN  12.0      12.0
4  5.0   NaN       5.0
7  NaN   8.0       8.0
 

Комментарии:

1. это не печатает вывод, как вы показали, пожалуйста, проверьте

2. Это вывод после выполнения вашего кода. 0 Nan 10 Nan

3. @сэм, Ты имеешь в виду только один ряд ? Это странно.

4. да. можете ли вы опубликовать полный код, чтобы попробовать с моей стороны?

5. @Sam Дай мне знать, если я еще чем-то могу помочь!: -)

Ответ №2:

Сложите фрейм данных, чтобы преобразовать его в многоиндексный ряд, затем сбросьте индекс уровня 1, затем с помощью логического фильтра индексирования/выберите только строки, за которыми min следует max или наоборот

 s = df[df != 'Nan'].stack().reset_index(name='combined', level=1)
m = s['level_1'] != s['level_1'].shift()
s[m].drop('level_1', 1)
 

    combined
0      10.0
1       4.0
2      12.0
4       5.0
7       8.0
 

Комментарии:

1. его печать не соответствует требуемому выходу.

2. Я думаю Nan , что значения являются строковыми в вашем фрейме данных, давайте сначала замаскируем Nan значения фактическими NaN , а затем попробуем решение.

3. я тоже проверил с фактическим Nan, но его вывод на печать не такой, как ожидалось

4. теперь он печатает все строки, можете ли вы опубликовать полный код, который вы пробовали, потому что он не работает

5. решение отлично работает с образцом фрейма данных, верно?

Ответ №3:

Что вы можете сделать, так это определить первый ключ для первого значения, которое вы хотите включить, например, «max», а затем выполнить итерацию по кадру данных и добавить значения в структуру данных при изменении ключа. В то же время вам придется проверить значения «NaN», так как у вас их много,

 combined = []
key = 'max'
for index, row in df.iterrows():
  if not row[key] != row[key]:
    combined.append(row[key])
    if key == 'max':
      key = 'min'
    else:
      key = 'max'
 

Здесь я только что жестко закодировал первое значение, но если вы не хотите этого делать, вы можете просто проверить, какой столбец в первой строке имеет фактическое значение, которое не является «NaN», а затем сделать его ключом.

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

Комментарии:

1. Дайте мне знать, если вам нужна логика того, как проверить, какой ключ следует использовать в первую очередь.

Ответ №4:

Если мои предположения верны, то это должно сработать.

  1. Значение-строка «Nan», а не np.NaN
  2. Если столбец min имеет значение «Nan», то столбец max будет иметь число, и наоборот, это означает, что ни одна строка не может иметь два числа.
 import numpy as np
import pandas as pd


data = [['Nan', 10], [4, 'Nan'], ['Nan', 12], ['Nan', 13], [5, 'Nan'], [6, 'Nan'], [7, 'Nan'], ['Nan', 8]]
df = pd.DataFrame(data, columns = ['min', 'max'])


df['combined'] = np.where(df['min']!='Nan', df['min'], df['max'])
 

Это результат, который я получаю

    min  max combined
0  Nan   10       10
1    4  Nan        4
2  Nan   12       12
3  Nan   13       13
4    5  Nan        5
5    6  Nan        6
6    7  Nan        7
7  Nan    8        8
 

Комментарии:

1. @SAKL требуется другой вывод, пожалуйста, проверьте вывод, опубликованный в вопросе