我有一个包含几列的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语句。
答案 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)
在三行上,这已经更快了:
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