在DataFrame中创建新列

时间:2017-06-13 20:13:08

标签: python pandas

我有一个包含几列的DataFrame:

   'a'  'b'  'c'  'd'
0  'x'   3    3    5
1  'y'   2    3    6
2  'z'   1    4    1

我想创建一些依赖于数据的新列。列中的每个可能值' a'我想要两个新列(我在列中列出了所有不同的值' a'。只有少数几个)。每列有两个条件:对于第一个新列,列' a'需要等于所需的值(例如' x')和列' b'等于列' c'。对于第二个新的,列' a'仍然需要等于所需的值,但列' b'需要等于列' d' (列' b'将等于' c'或' d')。如果两个条件都满足,则新列将获得1,否则将获得0。

以下是使用上述示例DataFrame查看的内容,具体如下:

一个。列的期望值' e' &安培; ' F'是' x'

湾列的期望值' g' &安培; ' H'是'

℃。列的期望值' j' &安培; ' K'是' z'

d。专栏'''' h'当列' b'和' c'是平等的

即专栏' f',' h',' k'当列' b'并且' d'是平等的

   'a'  'b'  'c'  'd'  'e'  'f'  'g'  'h'  'j'  'k'
0  'x'   3    3    5    1    0    0    0    0    0
1  'y'   2    3    6    0    0    0    0    0    0 
2  'z'   1    4    1    0    0    0    0    0    1

我尝试使用每个示例的apply函数。这就是我们想要测试x' x'那个栏目' b'和' c'是平等的:

data['d']= data.apply(lambda row: assignEvent(row, 'x', row['c']), axis=1 )

使用assignEvent函数:

def assignEvent(row, event, venue):
    """
    :param event: the desired event we're looking for
    :param venue: Either column 'c' or 'd' 
    """

    if (str(row['a'])==event) & (str(venue)==str(row['b'])):
            return 1
    else:
            return 0

它没有工作,因为当我完成新列中的所有值都是0.我不知道为什么,因为我测试了它,我知道我'进入我的函数中的if语句。

2 个答案:

答案 0 :(得分:1)

我改变了一些事情。首先,列a的数据有引号,因此我在assignEvent函数中删除了replace的数据。其次,我只将列名作为场地参数传递,让我们访问该函数中的那一列。

def assignEvent(row, event, venue):
    """
    :param event: the desired event we're looking for
    :param venue: Either column 'c' or 'd' 
    """

    if (row['a'].replace("'","")==event) & (row[venue]==row['b']):
            return 1
    else:
            return 0

df['dd']= df.apply(lambda row: assignEvent(row, 'x', 'c'), axis=1 )

输出:

     a  b  c  d  dd
0  'x'  3  3  5   1
1  'y'  2  3  6   0
2  'z'  1  4  1   0

答案 1 :(得分:1)

方法:

我将提出一种避免使用apply的方法,以提高速度和速度。缩放。看起来您实际上的目标是根据您在问题中列出的条件,为data['a']中的条目添加两个不同的指标变量集。如果这是不正确的,并且只有列a的值的一部分应该得到指标,请参见附录。

获取指标变量非常简单:

dummies = pd.get_dummies(data['a'])
dummies
Out[335]: 
   'x'  'y'  'z'
0    1    0    0
1    0    1    0
2    0    0    1

识别条件为真的行也很容易,这里使用numpy.where

显示
np.where(data['b'] == data['c'], 1, 0)

要合并这些,我们可以在使用np.where输出格式后稍微使用矩阵乘法:

np.array([np.where(data['b'] == data['c'], 1, 0)]).T*dummies
Out[338]: 
   'x'  'y'  'z'
0    1    0    0
1    0    0    0
2    0    0    0

要对这两种情况执行此操作,请将其与原始数据相关联,并按照指定的格式对其进行格式化,我将跳过以下内容:

def col_a_dummies(data):
    dummies = pd.get_dummies(data['a'])
    b_c = np.array([np.where(data['b'] == data['c'], 1, 0)]).T*dummies
    b_d = np.array([np.where(data['b'] == data['d'], 1, 0)]).T*dummies
    return pd.concat([data[['a', 'b', 'c', 'd']], b_c, b_d], axis=1)

def format_dummies(dummies):
    dummies.columns = ['a', 'b', 'c', 'd', 'e', 'g', 'j', 'f', 'h', 'k']
    return dummies.sort_index(axis=1)

data = format_dummies(col_a_dummies(data))
data
Out[362]: 
     a  b  c  d  e  f  g  h  j  k
0  'x'  3  3  5  1  0  0  0  0  0
1  'y'  2  3  6  0  0  0  0  0  0
2  'z'  1  4  1  0  0  0  0  0  1

<强>附录: 如果数据帧在被馈送到get_dummies之前首先被过滤,则此方法仍然很有效。这确实引入了需要对数据进行唯一索引的附加约束。

def filtered_col_a_dummies(data, values):
    filtered = data[data['a'].isin(values)]
    dummies = pd.get_dummies(filtered['a'])
    b_c = np.array([np.where(filtered['b'] == filtered['c'], 1, 0)]).T*dummies
    b_d = np.array([np.where(filtered['b'] == filtered['d'], 1, 0)]).T*dummies
    return pd.concat([data[['a', 'b', 'c', 'd']], b_c, b_d], axis=1).fillna(0)

%timeit结果

在三行上,这已经更快了:

def assignEvent(row, event, venue):
    """
    :param event: the desired event we're looking for
    :param venue: Either column 'c' or 'd' 
    """

    if (row['a']==event) & (row[venue]==row['b']):
            return 1
    else:
            return 0

def no_sort_format_dummies(dummies):
    dummies.columns = ['a', 'b', 'c', 'd', 'e', 'g', 'j', 'f', 'h', 'k']
    return dummies

%timeit data.apply(lambda row: assignEvent(row, "'x'", 'c'), axis=1)
1000 loops, best of 3: 467 µs per loop
# needs to be repeated six times in total, total time 2.80 ms, ignoring assignment

%timeit format_dummies(col_a_dummies(data))
100 loops, best of 3: 2.58 ms per loop

%timeit no_sort_format_dummies(col_a_dummies(data))
100 loops, best of 3: 2.07 ms per loop

如果没有对列进行排序。

如果已过滤:

%timeit format_dummies(filtered_col_a_dummies(data, ("'x'", "'y'", "'z'")))
100 loops, best of 3: 3.92 ms per loop

在300行上它变得更加明显:

%timeit data.apply(lambda row: assignEvent(row, "'x'", 'c'), axis=1)
100 loops, best of 3: 10.9 ms per loop

%timeit format_dummies(col_a_dummies(data))
100 loops, best of 3: 2.73 ms per loop

%timeit no_sort_format_dummies(col_a_dummies(data))
100 loops, best of 3: 2.14 ms per loop

%timeit format_dummies(filtered_col_a_dummies(data, ("'x'", "'y'", "'z'")))
100 loops, best of 3: 4.04 ms per loop