Панды: объединение двух столбцов в один с соответствующими значениями - PullRequest
3 голосов
/ 21 октября 2019

У меня есть большой фрейм данных с кучей имен, которые появляются в двух столбцах. Он находится в следующем макете

Winner    Value_W     Loser     Value_L

Jack         5         Sally       -3
Sally        2         Max         -1
Max          4         Jack        -2
Lucy         1         Jack        -6
Jack         6         Henry       -3
Henry        5         Lucy        -4

Затем я отфильтровал столбцы «Победитель» и «Проигравший», чтобы получить все строки, которыеДжек появляется при использовании следующего кода

pd.loc[(df['Winner'] == 'Jack') | (df['Loser'] == 'Jack')]

, который возвращает следующее:

Winner    Value_W    Loser    Value_L

Jack         5       Sally      -3
Max          4       Jack       -2
Lucy         1       Jack       -6
Jack         6       Henry      -3

Сейчас я ищу, чтобы сгенерировать один столбец, в котором есть только Джек и его соответствующие значения. Итак, в этом примере вывод, который мне нужен:

New_1    New_2

Jack     5
Jack    -2
Jack    -6
Jack     6

Я не уверен, как это сделать.

Ответы [ 6 ]

4 голосов
/ 21 октября 2019

Вы можете wide_to_long после небольшого переименования столбцов. Это позволяет вам собирать дополнительную информацию, например, является ли эта строка выигрышем или проигрышем. Или, если вам все равно, сделайте df1 = df1.reset_index(drop=True)

d = {'Winner': 'Person_W', 'Loser': 'Person_L'}
df1 = pd.wide_to_long(df.rename(columns=d).reset_index(),
                      stubnames=['Person', 'Value'],
                      i='index',
                      j='Win_Lose',
                      sep='_',
                      suffix='.*')

df1[df1.Person == 'Jack']
#               Person  Value
#index Win_Lose              
#0     W          Jack      5
#4     W          Jack      6
#2     L          Jack     -2
#3     L          Jack     -6

Если этот конкретный порядок важен, у нас все еще есть исходный индекс так:

df1.sort_index(level=0).query('Person == "Jack"').reset_index(drop=True) 
#  Person  Value
#0   Jack      5
#1   Jack     -2
#2   Jack     -6
#3   Jack      6
3 голосов
/ 22 октября 2019
name = 'Jack'
>>> pd.DataFrame({
    'New_1': name, 
    'New_2': df.loc[df['Winner'].eq(name), 'Value_W'].tolist() 
             + df.loc[df['Loser'].eq(name), 'Value_L'].tolist()})
  New_1  New_2
0  Jack      5
1  Jack      6
2  Jack     -2
3  Jack     -6
3 голосов
/ 21 октября 2019

Вы должны идти wide_to_long наверняка, но здесь есть скрытая функция, так называемая lreshape (может удалить в будущем, зависит от разработчика pandas)

pd.lreshape(df,{'name':['Winner','Loser'],'v':['Value_W','Value_L']}).query("name=='Jack'")
Out[75]: 
   name  v
0  Jack  5
4  Jack  6
8  Jack -2
9  Jack -6
1 голос
/ 21 октября 2019

Я думаю, вы могли бы использовать numpy.where после того, как вы выбрали только строки с 'Jack'

import numpy as np
df['New_2'] = np.where(df['Winner'] == 'Jack', df['Value_W'], df['Value_L'])
0 голосов
/ 22 октября 2019

Также DataFrame.where + DataFrame.shift с axis=1

new_df=df.where(df.eq('Jack').shift(axis=1)).sum(axis=1,min_count=1).dropna().to_frame('value')
new_df.insert(0,'Name','Jack')
print(new_df)

   Name  value
0  Jack    5.0
2  Jack   -2.0
3  Jack   -6.0
4  Jack    6.0
0 голосов
/ 21 октября 2019

Возможно:

  1. Разделить его на два кадра данных
  2. Переименовать несколько столбцов
  3. Присоединиться
  4. Возможно удалить дополнительные строки
df_win = df[['Winner', 'Value_W']].rename(columns={'Winner':'Name','Value_W':'Value'})
df_lose = df[['Loser', 'Value_L']].rename(columns={'Loser':'Name','Value_W':'Value'})

df = df_win.join(df_lose, on='Name', how='outer')
df.loc[df.Name == 'Jack']

Мне очень нравится ответ ALollz.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...