Как удалить дубликаты столбцов в Pandas DataFrame
import pandas as pd
import numpy as np
Как удалить дубликаты столбцов? Есть DataFrame, в котором столбцы под индексами 0, 1, 2 имеют одинаковые данные Как в такой ситуации получить чистый DataFrame?
Ответы (3 шт):
Воспользуйтесь методом .first_valid_index()
. Фрейм разделяем через индекс по колонкам -2
, т.е. считаем, что 2 правые колонки - это числа, а все начальные колонки - текст.
import pandas as pd
import numpy as np
df = pd.DataFrame({0: [np.nan, np.nan, np.nan, 'coconut', np.nan, 'walnut', np.nan, np.nan, np.nan, 'apricot'],
1: [np.nan, np.nan, 'peach', 'coconut', np.nan, 'walnut', 'pineapple', np.nan, np.nan, 'apricot'],
2: ['pear', 'strawberry', 'peach', 'coconut', np.nan, 'walnut', 'pineapple', 'grape', np.nan, 'apricot'],
3: [1, 2, 3, 4, np.nan, 12, 7, 11, np.nan, 14],
4: [10, 20, 30, 40, np.nan, 15, 9, 22, np.nan, 13]})
df = pd.concat([df.iloc[:, :-2].apply(lambda x: x[idx] if (idx := x.first_valid_index()) is not None else np.nan, axis=1), df.iloc[:, -2:]], axis=1).rename(columns={3: 1, 4: 2})
print(df)
0 1 2
0 pear 1.0 10.0
1 strawberry 2.0 20.0
2 peach 3.0 30.0
3 coconut 4.0 40.0
4 NaN NaN NaN
5 walnut 12.0 15.0
6 pineapple 7.0 9.0
7 grape 11.0 22.0
8 NaN NaN NaN
9 apricot 14.0 13.0
Еще вариант без .apply()
df = pd.concat([df.iloc[:, :-2].stack().groupby(level=0).first(), df.iloc[:, -2:]], axis=1).sort_index()
Пример у вас не очень валидный, у вас нет варианта, чтобы колонка 2 не покрывала все ваши потребности. Но могу предложить такой вариант для объединения данных трёх первых колонок обратно во вторую колонку. Потом остальные колонки можно отбросить:
df.iloc[:, 2] = df.iloc[:,:3].apply(lambda x: next(iter(set(x.dropna()) or set([np.NaN]))), axis=1)
df = df.iloc[:, 2:]
Пояснения:
df.iloc[:,:3]
- взять первые три колонкиapply(lambda x: ..., axis=1)
- применить к ним построчно функциюnext
- взять первое значение из последовательностиiter
- перебрать (множество)set(x.dropna())
- выкинутьNA
и схлопнуть одинаковые значения в одноor set([np.NaN])
- если получилось пустое множество, сделать множество из одного элементаNA
Если вы не знаете, сколько у вас колонок может быть с неполными данными, то можно воспользоваться советом от @CrazyElf и выбрать колонки по типу данных:
obj_cols = df.select_dtypes(include='object')
а затем:
df["res"] = obj_cols.apply(lambda x: pd.Series(x.dropna().values), axis=1)[0]
df = df.drop(columns=obj_cols.columns)
df:
3 4 res
0 1.0 10.0 pear
1 2.0 20.0 strawberry
2 3.0 30.0 peach
3 4.0 40.0 coconut
4 NaN NaN NaN
5 12.0 15.0 walnut
6 7.0 9.0 pineapple
7 11.0 22.0 grape
8 NaN NaN NaN
9 14.0 13.0 apricot