DataFrame有两列A
和B
整数。
a b
1 3
4 2
2 0
6 1
...
我需要以下列方式交换:
if df.a > df.b:
temp = df.b
df.b = df.a
df.a = temp
预期产出:
a b
1 3
2 4 <----
0 2 <----
1 6 <----
基本上总是在A列中有两个较小的值。
我觉得我应该使用loc
,但我找不到正确的方法。
答案 0 :(得分:4)
In [443]: df['a'], df['b'] = df.min(axis=1), df.max(axis=1)
In [444]: df
Out[444]:
a b
0 1 3
1 2 4
2 0 2
3 1 6
或
pd.DataFrame(np.sort(d.values, axis=1), d.index, d.columns)
答案 1 :(得分:3)
使用np.where
即可
In [21]: df.a, df.b = np.where(df.a > df.b, [df.b, df.a], [df.a, df.b])
In [23]: df
Out[23]:
a b
0 1 3
1 2 4
2 0 2
3 1 6
或,使用.loc
In [35]: cond = df.a > df.b
In [36]: df.loc[cond, ['a', 'b']] = df.loc[cond, ['b', 'a']].values
In [37]: df
Out[37]:
a b
0 1 3
1 2 4
2 0 2
3 1 6
或,.apply(np.sort, axis=1)
如果您需要较小的a
值且较大的b
In [54]: df.apply(np.sort, axis=1)
Out[54]:
a b
0 1 3
1 2 4
2 0 2
3 1 6
答案 2 :(得分:3)
看到@JohnGait和@MaxU提出的方法,我做了一个小的速度比较。
arr = np.random.randint(low = 100, size = (10000000, 2))
# using np.where
df = pd.DataFrame(arr, columns = ['a', 'b'])
t_0 = time.time()
df.a, df.b = np.where(df.a > df.b, [df.b, df.a], [df.a, df.b])
t_1 = time.time()
# using df.loc
df = pd.DataFrame(arr, columns = ['a', 'b'])
t_2 = time.time()
cond = df.a > df.b
df.loc[cond, ['a', 'b']] = df.loc[cond, ['b', 'a']].values
t_3 = time.time()
# using df.min
df = pd.DataFrame(arr, columns = ['a', 'b'])
t_4 = time.time()
df['a'], df['b'] = df.min(axis=1), df.max(axis=1)
t_5 = time.time()
# using np.sort
t_6 = time.time()
df_ = pd.DataFrame(np.sort(arr, axis=1), df.index, df.columns)
t_7 = time.time()
t_1 - t_0 # using np.where: 5.759037971496582
t_3 - t_2 # using .loc: 0.12156987190246582
t_5 - t_4 # using df.min: 1.0503261089324951
t_7 - t_6 # 0.20351791381835938
虽然第二种方法是最快的方法,但实际收益微不足道。我是出于迂腐的原因在这里添加的。我没有包括排序方法,因为我确信它会慢得多。
修改强>
由于我犯了错误,我错误地报告了np.where
的计算时间。纠正了(原来它是最慢的!)并添加了另一种方法(跟随@ MaxU的评论)
答案 3 :(得分:3)
<强>解决方案强>
它就像
numpy.array
发生了什么
我可以使用sort
方法对axis=1
进行排序。我传递参数values
以表示我想沿第一个轴排序(按行方向)。数据帧的numpy
属性访问基础df.values.sort(1)
数组。所以df.values[:] = np.sort(df.values, 1)
按行排序......完成基础值。
我们可以用
更明确一些df.values[:, ::-1] = np.sort(df.values, 1)
这使我们可以灵活地在列子集上执行此操作或反向排序
L <- list(cbind(b = 10),
cbind(a = 1:2, b = 2:3))
library(data.table)
rbindlist(lapply(L, as.data.table), fill = TRUE)
# b a
#1: 10 NA
#2: 2 1
#3: 3 2