熊猫:反对Liker调查答案

时间:2018-05-30 13:02:01

标签: python pandas

我有以下问题:

我的调查包含大量问题的答案,如:

EmptyList: List Nat
EmptyList = []

testCase: contrived (EmptyList, 'b', (1, 2.0), "hi", True) = False
testCase = Refl

问题在于并非所有问题都是在“同一方向”提出的。因此,Q1中的'5'答案将表明肯定的答案。但第二季度的5分将意味着一个强烈否定的答案。

我们目前正在手动重新编码所有问题(因此将所有Q2 5替换为1等),但我想知道是否有更快的方法来解决这个问题。

我考虑将所有答案除以5,然后减去1,但这从未给出整数。数学并不是我的强项,所以我想知道这里是否有人可以帮助我

4 个答案:

答案 0 :(得分:4)

您可以从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

答案 1 :(得分:2)

如果我理解正确,你可以这样做:

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

答案 2 :(得分:2)

我个人会这样做。

考虑您的示例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

答案 3 :(得分:0)

这是一个通用函数,它可以处理您可能想要反转代码的数据帧中的任意数量的列。让我们用一些示例数据试试

import pandas as pd

data1 = {
         'A': [3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
         'B': [9, 2, 3, 2, 4, 0, 2, 7, 2, 8],
         'C': [2, 4, 1, 0, 2, 1, 3, 0, 7, 8]
         }
df1 = pd.DataFrame(data1)

现在将反向编码列 A and B

中的数据的函数
# columns to reverse code
vars = ['A', 'B']

# define function to reverse code data
def reverse_code(data):
    cols = data.columns
    max_value = data.max(axis=0)
    if set(vars) & set(cols):
         data.loc[:, vars] = (max_value + 1) - data.loc[:, vars]
    
    return data
    

print('\nreverse-coded \n', reverse_code(df1))

df1
   A  B  C
0  3  9  2
1  3  2  4
2  3  3  1
3  3  2  0
4  3  4  2
5  3  0  1
6  3  2  3
7  3  7  0
8  3  2  7
9  3  8  8

reverse-coded
   A   B  C
0  1   1  2
1  1   8  4
2  1   7  1
3  1   8  0
4  1   6  2
5  1  10  1
6  1   8  3
7  1   3  0
8  1   8  7
9  1   2  8