在Python中高效转换数据帧不同的值

时间:2017-09-25 07:59:31

标签: python pandas dataframe

我有这样的数据:

republican,n,y,n,y,y,y,n,n,n,y,?,y,y,y,n,y
republican,n,y,n,y,y,y,n,n,n,n,n,y,y,y,n,?
democrat,?,y,y,?,y,y,n,n,n,n,y,n,y,y,n,n
democrat,n,y,y,n,?,y,n,n,n,n,y,n,y,n,n,y
democrat,y,y,y,n,y,y,n,n,n,n,y,?,y,y,y,y
democrat,n,y,y,n,y,y,n,n,n,n,n,n,y,y,y,y
democrat,n,y,n,y,y,y,n,n,n,n,n,n,?,y,y,y
republican,n,y,n,y,y,y,n,n,n,n,n,n,y,y,?,y
来自source

。 我想以最有效的方式将所有数据(dataframe)中的所有不同的不同值更改为数值。 在上面提到的例子中,我想改变共和党 - > 1和民主人士 - > 2,y - > 3,n-> 4和? - > 5(或NULL)。

我尝试使用以下内容:

# Convert string column to integer
def str_column_to_int(dataset, column):
    class_values = [row[column] for row in dataset]
    unique = set(class_values)
    lookup = dict()
    for i, value in enumerate(unique):
        lookup[value] = i
    for row in dataset:
        row[column] = lookup[row[column]]
    return lookup

但是,我不确定使用Pandas是否可以提高效率,或者还有其他更好的解决方案。 (这应该是任何数据源的通用)。 以下是使用dataframe将数据转换为Pandas

import pandas as pd
file_path = 'https://archive.ics.uci.edu/ml/machine-learning-databases/voting-records/house-votes-84.data'
dataset = pd.read_csv(file_path, header=None)

3 个答案:

答案 0 :(得分:2)

v = df.values

f = pd.factorize(v.ravel())[0].reshape(v.shape)

pd.DataFrame(f)

   0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15  16
0   0   1   2   1   2   2   2   1   1   1   2   3   2   2   2   1   2
1   0   1   2   1   2   2   2   1   1   1   1   1   2   2   2   1   3
2   4   3   2   2   3   2   2   1   1   1   1   2   1   2   2   1   1
3   4   1   2   2   1   3   2   1   1   1   1   2   1   2   1   1   2
4   4   2   2   2   1   2   2   1   1   1   1   2   3   2   2   2   2
5   4   1   2   2   1   2   2   1   1   1   1   1   1   2   2   2   2
6   4   1   2   1   2   2   2   1   1   1   1   1   1   3   2   2   2
7   0   1   2   1   2   2   2   1   1   1   1   1   1   2   2   3   2

答案 1 :(得分:2)

在整个数据框上使用replace来制作映射。您可以先为已知映射的字典传递需要保持一致的值,然后为数据集生成一组值,并将这些额外值映射为向上说出值100

例如,此处的?未映射,因此值为100

mappings = {'republican':1, 'democrat':2, 'y':3, 'n':4}
unknown = set(pd.unique(df.values.ravel())) - set(mappings.keys())
mappings.update([v, c] for c, v in enumerate(unknown, start=100))
df.replace(mappings, inplace=True)

给你:

   republican    n  n.1  n.2  n.3  n.4  n.5  n.6  n.7  n.8  n.9    ?  n.10  n.11  n.12  n.13  n.14
0           1    4    3    4    3    3    3    4    4    4    3  100     3     3     3     4     3
1           1    4    3    4    3    3    3    4    4    4    4    4     3     3     3     4   100
2           2  100    3    3  100    3    3    4    4    4    4    3     4     3     3     4     4
3           2    4    3    3    4  100    3    4    4    4    4    3     4     3     4     4     3
4           2    3    3    3    4    3    3    4    4    4    4    3   100     3     3     3     3
5           2    4    3    3    4    3    3    4    4    4    4    4     4     3     3     3     3
6           2    4    3    4    3    3    3    4    4    4    4    4     4   100     3     3     3
7           1    4    3    4    3    3    3    4    4    4    4    4     4     3     3   100     3

更通用的版本是:

mappings = {v:c for c, v in enumerate(sorted(set(pd.unique(df.values.ravel()))), start=1)}
df.replace(mappings, inplace=True)

答案 2 :(得分:1)

您可以使用:

v = df.values

a, b = v.shape
f = pd.factorize(v.T.ravel())[0].reshape(b,a).T

df = pd.DataFrame(f)
print (df)
   0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15  16
0   0   2   4   2   4   4   4   2   2   2   4   3   4   4   4   2   4
1   0   2   4   2   4   4   4   2   2   2   2   2   4   4   4   2   3
2   1   3   4   4   3   4   4   2   2   2   2   4   2   4   4   2   2
3   1   2   4   4   2   3   4   2   2   2   2   4   2   4   2   2   4
4   1   4   4   4   2   4   4   2   2   2   2   4   3   4   4   4   4
5   1   2   4   4   2   4   4   2   2   2   2   2   2   4   4   4   4
6   1   2   4   2   4   4   4   2   2   2   2   2   2   3   4   4   4
7   0   2   4   2   4   4   4   2   2   2   2   2   2   4   4   3   4