繁体   English   中英

如何将基于其他列值的列附加到pandas数据框

[英]How to append columns based on other column values to pandas dataframe

我有以下问题:我想将列追加到数据框。 这些列是此数据帧另一行中的唯一值,并填充了该值在此行中的出现。 看起来像这样:

df:

   Column1  Column2
0     1       a,b,c
1     2       a,e
2     3       a
3     4       c,f
4     5       c,f

我想要得到的是:

    Column1  Column2  a  b  c  e  f
0     1       a,b,c   1  1  1
1     2       a,e     1        1
2     3       a       1
3     4       c,f           1     1
4     5       c,f           1     1

(空格可以是nan或0,无关紧要。)

我现在已经编写了一些代码来接收该信息,但是它没有附加列,而是附加了行,因此我的输出看起来像这样:

        Column1  Column2
    0     1       a,b,c
    1     2       a,e
    2     3       a
    3     4       c,f
    4     5       c,f
    a     1        1
    b     1        1
    c     1        1
    e     1        1
    f     1        1

代码如下:

def NewCols(x):
    for i, value in df['Column2'].iteritems():
        listi=value.split(',')
        for value in listi:
            string = value
            x[string]=list.count(string)
    return x

df1=df.apply(NewCols)

我在这里要做的是遍历数据帧的每一行,并以逗号listi Column2中包含的字符串(a,b,c),因此变量listi是包含分隔字符串值的列表。 然后,对于每个值,我想创建一个新列,并在listi填充该值的出现listi 我很困惑为什么代码会附加行而不是列。 有人知道为什么以及如何纠正吗?

虽然可以使用get_dummies进行此操作,但我们也可以直接作弊并使用pd.value_counts

>>> df = pd.DataFrame({'Column1': {0: 1, 1: 2, 2: 3, 3: 4, 4: 5}, 'Column2': {0: 'a,b,c', 1: 'a,e', 2: 'a', 3: 'c,f', 4: 'c,f'}})
>>> df.join(df.Column2.str.split(",").apply(pd.value_counts).fillna(0))
   Column1 Column2  a  b  c  e  f
0        1   a,b,c  1  1  1  0  0
1        2     a,e  1  0  0  1  0
2        3       a  1  0  0  0  0
3        4     c,f  0  0  1  0  1
4        5     c,f  0  0  1  0  1

逐步,我们有

>>> df.Column2.str.split(",")
0    [a, b, c]
1       [a, e]
2          [a]
3       [c, f]
4       [c, f]
dtype: object
>>> df.Column2.str.split(",").apply(pd.value_counts)
    a   b   c   e   f
0   1   1   1 NaN NaN
1   1 NaN NaN   1 NaN
2   1 NaN NaN NaN NaN
3 NaN NaN   1 NaN   1
4 NaN NaN   1 NaN   1
>>> df.Column2.str.split(",").apply(pd.value_counts).fillna(0)
   a  b  c  e  f
0  1  1  1  0  0
1  1  0  0  1  0
2  1  0  0  0  0
3  0  0  1  0  1
4  0  0  1  0  1
>>> df.join(df.Column2.str.split(",").apply(pd.value_counts).fillna(0))
   Column1 Column2  a  b  c  e  f
0        1   a,b,c  1  1  1  0  0
1        2     a,e  1  0  0  1  0
2        3       a  1  0  0  0  0
3        4     c,f  0  0  1  0  1
4        5     c,f  0  0  1  0  1

使用apply ,它将为每一列调用一次函数,并以该列作为参数。 因此,NewCols中的x将设置为单列。 当您执行x[string] = list.count(string) ,您正在向该列添加值。 由于对每一列都调用apply ,因此您将以这种方式将值附加到这两列。

当您的计算仅取决于单个列的值时, apply不是正确的选择。 而是使用map 在这种情况下,您需要编写一个NewCol函数,该函数接受单个Column2值并返回单行的数据。 您可以将其作为dict返回,也可以方便地返回类似dict的对象(例如collections.Counter 然后,您需要将此新行数据包装到DataFrame中,并使用concat将其按列附加到现有数据。 这是一个例子:

def NewCols(val):
    return collections.Counter(val.split(','))

>>> pandas.concat([d, pandas.DataFrame.from_records(d.Column2.map(NewCols))], axis=1)
   Column1 Column2   a   b   c   e   f
0        1   a,b,c   1   1   1 NaN NaN
1        2     a,e   1 NaN NaN   1 NaN
2        3       a   1 NaN NaN NaN NaN
3        4     c,f NaN NaN   1 NaN   1
4        5     c,f NaN NaN   1 NaN   1

对于这个特殊的计算,你其实并不需要在所有写自己的功能,因为熊猫已经split内置的下一个操作.str方法访问。 因此,您可以执行以下操作:

>>> pandas.concat([d, pandas.DataFrame.from_records(d.Column2.str.split(',').map(collections.Counter))], axis=1)
   Column1 Column2   a   b   c   e   f
0        1   a,b,c   1   1   1 NaN NaN
1        2     a,e   1 NaN NaN   1 NaN
2        3       a   1 NaN NaN NaN NaN
3        4     c,f NaN NaN   1 NaN   1
4        5     c,f NaN NaN   1 NaN   1

您可以将以下内容用作:

import pandas as pd
import sklearn.feature_extraction.text

vect = sklearn.feature_extraction.text.CountVectorizer(binary=True,   token_pattern=u'(?u)\\b\\w+\\b')
df = ...
v = [a for a in df['Column2']]
new_df = df.combine_first( pd.DataFrame(vect.fit_transform(v).todense(), columns=vect.get_feature_names()) )
print new_df

干杯!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM