#python #pandas
#python #pandas
Вопрос:
Я пытаюсь изучить pandas и задаюсь вопросом, как можно достичь приведенного ниже…
Фрейм данных для начала:
df = pd.DataFrame({
'Name': ['Person1', 'Person1'],
'SetCode1': ['L6A', 'L6A'],
'SetDetail1': ['B', 'C'],
'SetCode2': ['G2G', 'G2G'],
'SetDetail2': ['B', 'B'],
})
Комментарии:
1. для начала я добавил пример вашего фрейма данных, так что, возможно, другие смогут вам помочь. Я не знаю ответа на этот вопрос, но я уверен, что кто-то другой ответит. Рекомендуется добавлять примеры данных в коде (не фото!), Чтобы другим было легко отвечать на ваши вопросы.
Ответ №1:
Попробуйте использовать pd.wide_to_long
и unstack
:
df = pd.DataFrame({
'Name': ['Person1', 'Person1'],
'SetCode1': ['L6A', 'L6A'],
'SetDetail1': ['B', 'C'],
'SetCode2': ['G2G', 'G2G'],
'SetDetail2': ['B', 'B'],
})
df_melt = pd.wide_to_long(df.reset_index(),
['SetCode', 'SetDetail'],
['index', 'Name'],
'No')
df_out = df_melt.set_index('SetCode', append=True)
.reset_index(level=2, drop=True)['SetDetail']
.unstack()
df_out
Вывод:
SetCode G2G L6A
index Name
0 Person1 B B
1 Person1 B C
Ответ №2:
Я думаю, это скорее переименование столбцов, чем поворот. вот мой код
code_cols = list(filter(lambda s: s.startswith('SetCode'), df.columns))
det_cols = list(filter(lambda s: s.startswith('SetDetail'), df.columns))
codes = [df[s][0] for s in code_cols]
df.rename(columns = dict(zip(det_cols, codes)), inplace=True)
df.drop(columns = code_cols, inplace=True)
df
производит
Name L6A G2G
0 Person1 B B
1 Person1 C B
Спасибо @Sander van den Oord за ввод данных в dataframe!
Ответ №3:
Использование pandas.wide_to_long
— правильное решение, хотя нужно быть осторожным со NaN
значениями, которые у вас есть в определенных столбцах.
Поэтому здесь следует адаптация ответа Скотта Бостона:
import pandas as pd
# I just allowed myself to write 'Person2' instead of 'Person1' at the second row
# of the DataFrame, as I imagine this is what was originally intended in the data,
# but this does not change the method
df = pd.DataFrame({
'Name': ['Person1', 'Person2'],
'SetCode1': ['L6A', 'L6A'],
'SetDetail1': ['B', 'C'],
'SetCode6': ['U2H', None],
'SetDetail6': ['B', None],
})
print(df)
Name SetCode1 SetDetail1 SetCode6 SetDetail6
0 Person1 L6A B U2H B
1 Person2 L6A C None None
# You will need to use reset_index to keep the original index moving forward only if
# the 'Name' column does not have unique values
df_melt = pd.wide_to_long(df, ['SetCode', 'SetDetail'], ['Name'], 'No')
df_out = df_melt[df_melt['SetCode'].notnull()]
.set_index('SetCode', append=True)
.reset_index(level=1, drop=True)['SetDetail']
.unstack()
print(df_out)
SetCode L6A U2H
Name
Person1 B B
Person2 C NaN