在Python中将数据帧字符串转换为多个虚拟变量

时间:2017-09-07 23:26:17

标签: python dataframe data-processing

我有一个包含多个列的数据框。一列是“category”,它是一个空格分隔的字符串。 df类别的样本是:

             3 36 211 433 474 533 690 980
                                 3 36 211
                  3 16 36 211 396 398 409
                        3 35 184 590 1038
                67 179 208 1008 5000 5237

我有另一个类别列表dict = [3,5,7,8,16,5000]。 我想看到的是一个新的数据框,其中dict为列,0/1为条目。如果df中的行包含dict条目,则为1,否则为0.因此输出为:

3  5  7  8  16  36 5000
1  0  0  0  0   1   0
1  0  0  0  0   1   0
1  0  0  0  1   1   0 
1  0  0  0  0   0   0 
0  0  0  0  0   0   1

尝试过类似的事情:

for cat in level_0_cat:
    df[cat] = df.apply(lambda x: int(cat in map(int, x.category)), axis = 1)

但它不适用于大型数据集(1000万行)。也尝试了isin,但还没弄明白。任何想法都表示赞赏。

2 个答案:

答案 0 :(得分:0)

应该这样做。

# Read your data
>>> s = pd.read_clipboard(sep='|', header=None)

# Convert `cats` to string to make `to_string` approach work below
>>> cats = list(map(str, [3,4,7,8,16,36,5000]))
>>> cats
['3', '4', '7', '8', '16', '36', '5000']

# Nested list comprehension... Checks whether each `c` in `cats` exists in each row
>>> encoded = [[1 if v in set(s.ix[idx].to_string().split()) else 0 for idx in s.index] for v in cats]
>>> encoded
[[1, 1, 1, 1, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 0, 1]]


>>> import numpy as np

# Convert the whole thing to a dataframe to add columns
>>> encoded = pd.DataFrame(data=np.matrix(encoded).T, columns=cats)
>>> encoded
   3  4  7  8  16  36  5000
0  1  0  0  0   0   1     0
1  1  0  0  0   0   1     0
2  1  0  0  0   1   1     0
3  1  0  0  0   0   0     0
4  0  0  0  0   0   0     1

编辑:在没有直接调用任何pandas索引方法(如ixloc的情况下)的答案方式。

encoded = [[1 if v in row else 0 for row in s[0].str.split().map(set)] for v in cats]

encoded
Out[18]: 
[[1, 1, 1, 1, 0],
 [0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 0, 1, 0, 0],
 [1, 1, 1, 0, 0],
 [0, 0, 0, 0, 1]]

encoded = pd.DataFrame(data=np.matrix(encoded).T, columns=cats)

encoded
Out[20]: 
   3  4  7  8  16  36  5000
0  1  0  0  0   0   1     0
1  1  0  0  0   0   1     0
2  1  0  0  0   1   1     0
3  1  0  0  0   0   0     0
4  0  0  0  0   0   0     1

答案 1 :(得分:0)

您不需要将每一行转换为整数,它更简单 将字符串转换为字符串...

categories = [l.strip() for l in '''\
         3 36 211 433 474 533 690 980
                             3 36 211
              3 16 36 211 396 398 409
                    3 35 184 590 1038
            67 179 208 1008 5000 5237'''.split('\n')]

result = [3,5,7,8,16,5000]
d = [str(n) for n in result]
for category in categories:
    result.append([1 if s in category else 0 for s in d])

请不要使用dict(这是内置函数)来命名您的一个对象。