猿问

在 pandas 数据框中的两列之间传输值

我有一个像这样的熊猫数据框:


p q

0.5 0.5

0.6 0.4

0.3 0.7

0.4 0.6

0.9 0.1

所以,我想知道,如何将较大的值传输到 p 列,反之亦然的 q 列(将较小的值传输到 q 列),如下所示:


p q

0.5 0.5

0.6 0.4

0.7 0.3

0.6 0.4

0.9 0.1


炎炎设计
浏览 137回答 4
4回答

陪伴而非守候

您可以存储一些条件系列np.where(),然后将它们应用到数据帧:s1 = np.where(df['p'] < df['q'], df['q'], df['p'])s2 = np.where(df['p'] > df['q'], df['q'], df['p'])df['p'] = s1df['q'] = s2dfOut[1]:&nbsp;&nbsp; &nbsp; &nbsp;p&nbsp; &nbsp; q0&nbsp; 0.5&nbsp; 0.51&nbsp; 0.6&nbsp; 0.42&nbsp; 0.7&nbsp; 0.33&nbsp; 0.6&nbsp; 0.44&nbsp; 0.9&nbsp; 0.1您还可以使用.where():s1 = df['p'].where(df['p'] > df['q'], df['q'])s2 = df['p'].where(df['p'] < df['q'], df['q'])df['p'] = s1df['q'] = s2df我测试了从 100 行到 100 万行的不同行的执行时间,需要通过的答案axis=1可以是10,000 times slower!:Erfan 的 numpy 答案看起来是大型数据集以毫秒为单位执行最快的答案我的.where()答案也具有出色的性能,可以将执行时间保持在毫秒内(我假设 `np.where() 会有类似的结果。我以为MHDG7的答案会是最慢的,但实际上它比Alexander的答案更快。我猜亚历山大的回答很慢,因为它需要通过axis=1。事实上,MGDG7 和 Alexander 的答案是逐行的(带有axis=1),这意味着对于大型数据帧来说,它会大大减慢速度。正如您所看到的,一百万行数据帧需要几分钟才能执行。而且,如果您有 1000 万行到 1 亿行的数据帧,这些单行代码可能需要几个小时才能执行。from timeit import timeitdf = d.copy()def df_where(df):&nbsp; &nbsp; s1 = df['p'].where(df['p'] > df['q'], df['q'])&nbsp; &nbsp; s2 = df['p'].where(df['p'] < df['q'], df['q'])&nbsp; &nbsp; df['p'] = s1&nbsp; &nbsp; df['q'] = s2&nbsp; &nbsp; return dfdef agg_maxmin(df):&nbsp; &nbsp; df[['p', 'q']] = df[['p', 'q']].agg([max, min], axis=1)&nbsp; &nbsp; return dfdef np_flip(df):&nbsp; &nbsp; df = pd.DataFrame(np.flip(np.sort(df), axis=1), columns=df.columns)&nbsp; &nbsp; return dfdef lambda_x(df):&nbsp; &nbsp; df = df.apply(lambda x: [x['p'],x['q']] if x['p']>x['q'] else [x['q'],x['p']],axis=1,result_type='expand')&nbsp; &nbsp; return dfres = pd.DataFrame(&nbsp; &nbsp; index=[20, 200, 2000, 20000, 200000],&nbsp; &nbsp; columns='df_where agg_maxmin np_flip lambda_x'.split(),&nbsp; &nbsp; dtype=float)for i in res.index:&nbsp; &nbsp; d = pd.concat([df]*i)&nbsp; &nbsp; for j in res.columns:&nbsp; &nbsp; &nbsp; &nbsp; stmt = '{}(d)'.format(j)&nbsp; &nbsp; &nbsp; &nbsp; setp = 'from __main__ import d, {}'.format(j)&nbsp; &nbsp; &nbsp; &nbsp; print(stmt, d.shape)&nbsp; &nbsp; &nbsp; &nbsp; res.at[i, j] = timeit(stmt, setp, number=1)res.plot(loglog=True);

慕容森

用于numpy.sort按水平轴升序排序,然后翻转数组axis=1:df = pd.DataFrame(np.flip(np.sort(df), axis=1), columns=df.columns)&nbsp; &nbsp; &nbsp;p&nbsp; &nbsp; q0&nbsp; 0.5&nbsp; 0.51&nbsp; 0.6&nbsp; 0.42&nbsp; 0.7&nbsp; 0.33&nbsp; 0.6&nbsp; 0.44&nbsp; 0.9&nbsp; 0.1

至尊宝的传说

使用agg,传递函数列表(max和min)并指定axis=1将这些函数按行应用于列。df[['p', 'q']] = df[['p', 'q']].agg([max, min], axis=1)>>> df     p    q0  0.5  0.51  0.6  0.42  0.7  0.33  0.6  0.44  0.9  0.1简单的解决方案并不总是最有效的(例如上面的解决方案)。以下解决方案明显更快。p它屏蔽列小于列的数据帧q,然后交换值。mask = df['p'].lt(df['q'])df.loc[mask, ['p', 'q']] = df.loc[mask, ['q', 'p']].to_numpy()>>> df     p    q0  0.5  0.51  0.6  0.42  0.7  0.33  0.6  0.44  0.9  0.1

千巷猫影

您可以使用应用功能:df[['p','q']]&nbsp;=&nbsp;df.apply(lambda&nbsp;x:&nbsp;[x['p'],x['q']]&nbsp;if&nbsp;x['p']>x['q']&nbsp;else&nbsp;[x['q'],x['p']],axis=1,result_type='expand'&nbsp;)
随时随地看视频慕课网APP

相关分类

Python
我要回答