Вычесть значения в столбце в зависимости от групп столбцов - PullRequest
0 голосов
/ 27 мая 2020

У меня есть следующий фрейм данных с примерно 5000 записями.

df = pd.DataFrame({'name':['Strain A', 'Strain B', 'Strain C', 'Strain A', 'Strain B', 'Strain C','Strain A', 'Strain B', 'Strain C','Strain A', 'Strain B', 'Strain C', 'Strain A', 'Strain B', 'Strain C','Strain A', 'Strain B',],
               'Buffer':['PBS', 'PBS', 'PBS', 'Tris', 'Tris', 'Tris', 'Phos','Phos','Phos','PBS', 'PBS', 'PBS', 'Tris', 'Tris', 'Tris', 'Phos','Phos'],
               'Time' :[2,2,2,2,2,2,2,2,2,20,20,20,20,20,20,20,20],
               '%':[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17]
               }).set_index('name')



        Buffer  Time   %
name                     
Strain A  PBS    2     1 
Strain B  PBS    2     2 
Strain C  PBS    2     3 
Strain A  Tris   2     4 
Strain B  Tris   2     5 
Strain C  Tris   2     6 
Strain A  Phos   2     7 
Strain B  Phos   2     8 
Strain C  Phos   2     9 
Strain A  PBS    20    10
Strain B  PBS    20    11
Strain C  PBS    20    12
Strain A  Tris   20    13
Strain B  Tris   20    14
Strain C  Tris   20    15
Strain A  Phos   20    16
Strain B  Phos   20    17

Я хочу создать новый df, в котором я вычитаю значение% через 20-часовые моменты времени% из 2-часовых временных точек. Я пробовал несколько решений, которые обычно заканчиваются NaN. Я хотел бы получить df, подобное этому:

         Buffer  %
name              
Strain A  PBS    9
Strain B  PBS    9
Strain C  PBS    9
Strain A  Tris   9
Strain B  Tris   9
Strain C  Tris   9
Strain A  Phos   9
Strain B  Phos   9
Strain C  Phos  -9

Спасибо за помощь!

1 Ответ

0 голосов
/ 27 мая 2020

Я создал уникальный идентификатор для двух разных «стеков» в вашей таблице, а затем использовал этот идентификатор как индекс merge. Pandas добавит суффикс, чтобы ваши имена были уникальными. Затем вы можете выполнить простое вычитание:

df = pd.DataFrame({'name':['Strain A', 'Strain B', 'Strain C', 'Strain A', 'Strain B', 'Strain C','Strain A', 'Strain B', 'Strain C','Strain A', 'Strain B', 'Strain C', 'Strain A', 'Strain B', 'Strain C','Strain A', 'Strain B',],
           'Buffer':['PBS', 'PBS', 'PBS', 'Tris', 'Tris', 'Tris', 'Phos','Phos','Phos','PBS', 'PBS', 'PBS', 'Tris', 'Tris', 'Tris', 'Phos','Phos'],
           'Time' :[2,2,2,2,2,2,2,2,2,20,20,20,20,20,20,20,20],
           '%':[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17]
           }).set_index('name')


df["unique"] = df.index + "_" + df["Buffer"]
df1 = df[df["Time"]==2]
df2 = df[df["Time"]==20]

df3 = pd.merge(df1,df2,left_on='unique',right_on='unique',how='inner')
df3["Diff"] = df3["%_y"] - df3["%_x"]

Вероятно, есть более короткий и умный способ, но он, вероятно, более поучителен.

EDIT:

Чтобы учесть недостающие данные , вы можете выбрать how='outer', который заполнит NaN там, где есть пропущенные значения, а затем использовать

df3 = df3.fillna(0.0)

перед вычитанием

...