Панды: обратные ответы на опрос Лайкер - PullRequest
0 голосов
/ 30 мая 2018

У меня следующая проблема:

У меня есть опрос, который содержит большое количество ответов на вопросы Ликерта, например:

id | Q1 | Q2 | Q3
1     5    3    1
2     3    4    1
3     2    3    1

Проблема в том, что не все вопросыспросил в том же направлении.Таким образом, ответ «5» в Q1 будет указывать на положительный ответ.Но 5 в Q2 будет означать сильно отрицательный ответ.

В настоящее время мы перекодируем все вопросы вручную (таким образом, заменяя все Q2 5 на 1 и т. Д.), Но мне было интересно, есть ли более быстрый способ решить эту проблему.

Я думал оразделив все ответы на 5, а затем вычтя 1, но это никогда не дает мне целых чисел.Математика на самом деле не моя сильная сторона, поэтому мне было интересно, может ли кто-нибудь здесь помочь мне

Ответы [ 3 ]

0 голосов
/ 30 мая 2018

Я бы лично сделал это.

Учитывая ваш пример data.csv ...

id,q1,q2,q3
1,5,3,1
2,3,4,1
3,2,3,1

Мое решение подойдет ...

import pandas as pd

df = pd.read_csv('test_csv.csv')
print df
    id  q1  q2  q3
0   1   5   3   1
1   2   3   4   1
2   3   2   3   1

my_rates = [1, 2, 3, 4, 5]
df['q2'] = df['q2'].apply(lambda x:my_rates[-x])
print df
   id  q1  q2  q3
0   1   5   3   1
1   2   3   2   1
2   3   2   3   1

Тест

При больших наборах данных результаты резко меняются.

import pandas as pd
import timeit

df = pd.read_csv('test_csv.csv')
df = pd.concat([df] * 1000, ignore_index=True)

def imcoins(df):
    my_rates = [1, 2, 3, 4, 5]
    df['Q2'] = df['Q2'].apply(lambda x:my_rates[-x])
    return df

def joe(df):
    df['Q2'] = df['Q2'].map({1:5, 2:4, 3:3, 4:2, 5:1})
    return df

def jez(df):
    df.Q2 = 6 - df.Q2
    return df

def jez_2(df):
    df.Q2 = df.Q2.rsub(6)
    return df

def jez_3(df):
    df.Q2 = 6 - df.Q2.values
    return df

nb = 10000
t1 = timeit.timeit(stmt='imcoins(df)', setup='from __main__ import imcoins, df', number=nb)
t2 = timeit.timeit(stmt='joe(df)', setup='from __main__ import joe, df', number=nb)
t3 = timeit.timeit(stmt='jez(df)', setup='from __main__ import jez, df', number=nb)
t4 = timeit.timeit(stmt='jez_2(df)', setup='from __main__ import jez_2, df', number=nb)
t5 = timeit.timeit(stmt='jez_3(df)', setup='from __main__ import jez_3, df', number=nb)

print 'IMCoins : {}\njoe : {}\njezrael_1 : {}\njezrael_2 : {}\tjezrael_3 : {}'.format(t1, t2, t3, t4, t5)

# Python 2.7
IMCoins : 3.85911526513
joe : 1.26151379163
jezrael_1 : 0.487986194544
jezrael_2 : 0.613230951967
jezrael_3 : 0.287318529541

# Python 3.6
IMCoins : 2.0433933256597467
joe : 1.3545644831475654
jezrael_1 : 0.482208606992109
jezrael_2 : 0.5195013265458606
jezrael_3 : 0.27176954323496627
0 голосов
/ 30 мая 2018

Вы можете вычесть 6 из столбца Q2 или использовать rsub что вычесть с правой стороны:

print (df)
   Q1  Q2  Q3
0   5   3   1
1   3   4   1
2   2   5   1

df.Q2 = 6 - df.Q2
#same as
#df.Q2 = df.Q2.rsub(6)

Если важна производительность, вычтите на numpy array:

df.Q2 = 6 - df.Q2.values

Или:

df.Q2 = df.eval(' 6 - Q2')

Или:

import numexpr

x = df.Q2.values
df.Q2 = numexpr.evaluate('(6 - x)')


print (df)
   Q1  Q2  Q3
0   5   3   1
1   3   2   1
2   2   1   1
0 голосов
/ 30 мая 2018

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

df['Q2'] = df['Q2'].map({1:5, 2:4, 3:3, 4:2, 5:1})

Ввод:

   Q1  Q2  Q3
0   5   3   1
1   3   4   1
2   2   5   1

Вывод:

   Q1  Q2  Q3
0   5   3   4
1   3   2   1
2   2   1   1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...