为了账号安全,请及时绑定邮箱和手机立即绑定

熊猫系列的二进制移位

熊猫系列的二进制移位

RISEBY 2021-12-26 10:42:31
我在熊猫数据框中有一些布尔变量,我需要获取所有唯一的元组。所以我的想法是创建一个新的变量连接值列,然后使用 pandas.DataFrame.unique() 来获取所有唯一的元组。所以我的想法是使用二进制开发进行连接。例如,对于数据框:import pandas as pddf = pd.DataFrame({'v1':[0,1,0,0,1],'v2':[0,0,0,1,1], 'v3':[0,1,1,0,1], 'v4':[0,1,1,1,1]})我可以这样创建一个列:df['added'] = df['v1'] + df['v2']*2 + df['v3']*4 + df['v4']*8我的想法是迭代这样的变量列表(应该注意,在我的真正问题上,我不知道列数):variables = ['v1', 'v2', 'v3', 'v4']df['added'] = df['v1']for ind, var in enumerate(variables[1:]) :   df['added'] = df['added'] + df[var] << ind但是,这会引发错误:“TypeError:<<:'Series' 和 'int' 不支持的操作数类型。我可以用 pandas.DataFrame.apply() 解决我的问题:variables = ['v1', 'v2', 'v3', 'v4']df['added'] = df['v1']for ind, var in enumerate(variables[1:]) :   df['added'] = df['added'] + df[var].apply(lambda x : x << ind )但是, apply (通常)很慢。我怎样才能更有效地做事?
查看完整描述

3 回答

?
肥皂起泡泡

TA贡献1829条经验 获得超6个赞

使用这个解决方案,只是简化,因为排序已经交换:


df['new'] = df.values.dot(1 << np.arange(df.shape[-1]))

print (df)

   v1  v2  v3  v4  new

0   0   0   0   0    0

1   1   0   1   1   13

2   0   0   1   1   12

3   0   1   0   1   10

4   1   1   1   1   15

1000行和 4 列的性能:


np.random.seed(2019)


N= 1000

df = pd.DataFrame(np.random.choice([0,1], size=(N, 4)))

df.columns = [f'v{x+1}' for x in df.columns]


In [60]: %%timeit

    ...: df['new'] = df.values.dot(1 << np.arange(df.shape[-1]))

113 µs ± 1.45 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

尤卡解决方案:


In [65]: %%timeit

    ...: variables = ['v1', 'v2', 'v3', 'v4']

    ...: df['added'] = df['v1']

    ...: for ind, var in enumerate(variables[1:]) :

    ...:     df['added'] = df['added'] + [x<<ind for x in df[var]]

    ...: 

1.82 ms ± 16.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

原解决方案:


In [66]: %%timeit

    ...: variables = ['v1', 'v2', 'v3', 'v4']

    ...: df['added'] = df['v1']

    ...: for ind, var in enumerate(variables[1:]) :

    ...:    df['added'] = df['added'] + df[var].apply(lambda x : x << ind )

    ...: 

3.14 ms ± 8.52 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)


查看完整回答
反对 回复 2021-12-26
?
守着一只汪

TA贡献1872条经验 获得超3个赞

获得唯一的行是相同的操作drop_duplicates。(通过找到所有重复的行并删除它们,它只留下唯一的行。)

df[["v2","v3","v4"]].drop_duplicates()


查看完整回答
反对 回复 2021-12-26
?
慕桂英3389331

TA贡献2036条经验 获得超8个赞

在回答您关于更有效替代方案的问题时,我发现列表理解确实对您有所帮助:


variables = ['v1', 'v2', 'v3', 'v4']

df['added'] = df['v1']

for ind, var in enumerate(variables[1:]) :

    %timeit df['added'] = df['added'] + [x<<ind for x in df[var]]


308 µs ± 22.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

322 µs ± 19 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

316 µs ± 10.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

所以 315 µs 与:


variables = ['v1', 'v2', 'v3', 'v4']

df['added'] = df['v1']

for ind, var in enumerate(variables[1:]) :

    %timeit df['added'] = df['added'] + df[var].apply(lambda x : x << ind )


500 µs ± 38.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

503 µs ± 32.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

481 µs ± 32 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

作为免责声明,我不同意总和的价值,但这是一个不同的话题:)


查看完整回答
反对 回复 2021-12-26
  • 3 回答
  • 0 关注
  • 205 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信