Изменение формы csv с помощью Pandas: объединение двух подмножеств df

Мой .csv выглядит так:

   Res          X      XB          XC           O       P
  A312      76.55     -           -           -       -  
  B313      175.4   62.28       32.62       8.189   121.2
  J314      176.5   53.34       40.77       8.277   124.6
  L315      177.9   55.29       41.44       8.427   125.5
  T316      174.7   59.47       63.43       8.264   116.1
  ...
  G378      10.2    58.91       40.13       7.646   126.7 

Я хотел бы изменить его следующим образом:

   312 A   X   76.55
   313 B   X   175.4
   313 B   XB  62.28
   313 B   XC  32.62
   ...
   378 G   O   7.646
   378 G   P   126.7
import pandas as pd

df1 = pd.read_csv("my_file.csv", delim_whitespace = True, index_col = False, na_values = "-")
df2 = pd.read_csv("my_file.csv", delim_whitespace = True, index_col = False, na_values = "-")

df1['Pos'] = df1['Res'].str[1:].astype(int)
df1['AA'] = df1['Res'].str[0]
df2.drop('Res', axis = 1, inplace = True)
a = df2.stack(level = -1)
b = df1[["Pos", "AA"]]
print(a)
print(b)

это дает:

Выход из print(a):

0   X      76.500
1   X     175.400
    XB     62.280
    XC     32.620
    O       8.189
    P     121.200
...
62  X      10.200
    XB     58.910
    XC     40.130
    O       7.646
    P     126.700

Выход из print(b):

0   312  A
1   313  B
2   314  J
3   315  L
...
62  378  G

Любые идеи о том, как я могу сделать последний шаг, то есть объединить эти два df, a и b, и, наконец, достичь желаемого формата? Я уже попробовал несколько функций pandas, таких как pd.merge, pd.join и pd.concat. Кажется, ни один из них не работает...

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
0
29
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы хотите melt:

import pandas as pd

df = pd.read_csv("my_file.csv", delim_whitespace=True, index_col=False)

df['Res'] = df['Res'].str[0]
reshaped = df.melt('Res', ['X', 'XB', 'XC', 'O', 'P'])
print(reshaped.dropna().sort_values('Res').reset_index(drop=True))

Выход:

   Res variable  value
0    A        X  76.55
1    B        O  8.189
2    B        P  121.2
3    B        X  175.4
4    B       XB  62.28
5    B       XC  32.62
6    J        O  8.277
7    J        P  124.6
8    J        X  176.5
9    J       XB  53.34
10   J       XC  40.77
11   L        O  8.427
12   L        P  125.5
13   L        X  177.9
14   L       XB  55.29
15   L       XC  41.44
16   T        O  8.264
17   T        P  116.1
18   T        X  174.7
19   T       XB  59.47
20   T       XC  63.43

Эй, спасибо за предложение. Кажется, это действительно работает, но результат немного отличается от того, что я хотел. Скопировав ваш код, вы получите список (он отображается в алфавитном порядке для «Res», в то время как я хотел бы, чтобы он был упорядочен как число, отображаемое после буквы в моей исходной таблице, т.е. A312 ---> 312 A ). Алфавитный порядок также делает столбцы переменных довольно запутанными!

Shawn Marion fan 08.04.2019 10:15

@ShawnMarionfan, плохо, я неправильно понял ваши ожидаемые данные.

gmds 08.04.2019 10:18
Ответ принят как подходящий

Немного изменил ваше решение - сначала добавил DataFrame.pop для столбца извлечения - тогда df1.drop('Res', axis = 1, inplace = True) не нужен, затем создайте MultiIndex по DataFrame.set_index и вызовите DataFrame.stack, последняя очистка данных - reset_index с rename:

df1 = pd.read_csv("my_file.csv", delim_whitespace = True, index_col = False, na_values = "-")

df1['Pos'] = df1['Res'].str[1:].astype(int)
df1['AA'] = df1.pop('Res').str[0]

df = (df1.set_index(['Pos', 'AA'])
         .stack()
         .reset_index(name='new')
         .rename(columns = {'level_2':'cat'}))

print (df)
    Pos AA cat      new
0   312  A   X   76.550
1   313  B   X  175.400
2   313  B  XB   62.280
3   313  B  XC   32.620
4   313  B   O    8.189
5   313  B   P  121.200
6   314  J   X  176.500
7   314  J  XB   53.340
8   314  J  XC   40.770
9   314  J   O    8.277
10  314  J   P  124.600
11  315  L   X  177.900
12  315  L  XB   55.290
13  315  L  XC   41.440
14  315  L   O    8.427
15  315  L   P  125.500
16  316  T   X  174.700
17  316  T  XB   59.470
18  316  T  XC   63.430
19  316  T   O    8.264
20  316  T   P  116.100
21  378  G   X   10.200
22  378  G  XB   58.910
23  378  G  XC   40.130
24  378  G   O    7.646
25  378  G   P  126.700

Другие вопросы по теме