[英]Swapping column values based on column conditions (Pandas DataFrame)
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
但我找不到正確的方法。
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)
使用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
或者 ,如果您需要更小a
值和更大的b
,則.apply(np.sort, axis=1)
In [54]: df.apply(np.sort, axis=1)
Out[54]:
a b
0 1 3
1 2 4
2 0 2
3 1 6
看到@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的評論)
解
這很簡單
df.values.sort(1)
df
a b
0 1 3
1 2 4
2 0 2
3 1 6
發生了什么
我可以使用sort
方法對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)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.