4 回答

TA貢獻1757條經(jīng)驗 獲得超8個贊
您可以存儲一些條件系列np.where(),然后將它們應(yīng)用到數(shù)據(jù)幀:
s1 = np.where(df['p'] < df['q'], df['q'], df['p'])
s2 = np.where(df['p'] > df['q'], df['q'], df['p'])
df['p'] = s1
df['q'] = s2
df
Out[1]:
p q
0 0.5 0.5
1 0.6 0.4
2 0.7 0.3
3 0.6 0.4
4 0.9 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'] = s1
df['q'] = s2
df
我測試了從 100 行到 100 萬行的不同行的執(zhí)行時間,需要通過的答案axis=1
可以是10,000 times slower!
:
Erfan 的 numpy 答案看起來是大型數(shù)據(jù)集以毫秒為單位執(zhí)行最快的答案
我的
.where()
答案也具有出色的性能,可以將執(zhí)行時間保持在毫秒內(nèi)(我假設(shè) `np.where() 會有類似的結(jié)果。我以為MHDG7的答案會是最慢的,但實際上它比Alexander的答案更快。
我猜亞歷山大的回答很慢,因為它需要通過
axis=1
。事實上,MGDG7 和 Alexander 的答案是逐行的(帶有axis=1
),這意味著對于大型數(shù)據(jù)幀來說,它會大大減慢速度。
正如您所看到的,一百萬行數(shù)據(jù)幀需要幾分鐘才能執(zhí)行。而且,如果您有 1000 萬行到 1 億行的數(shù)據(jù)幀,這些單行代碼可能需要幾個小時才能執(zhí)行。
from timeit import timeit
df = d.copy()
def df_where(df):
s1 = df['p'].where(df['p'] > df['q'], df['q'])
s2 = df['p'].where(df['p'] < df['q'], df['q'])
df['p'] = s1
df['q'] = s2
return df
def agg_maxmin(df):
df[['p', 'q']] = df[['p', 'q']].agg([max, min], axis=1)
return df
def np_flip(df):
df = pd.DataFrame(np.flip(np.sort(df), axis=1), columns=df.columns)
return df
def lambda_x(df):
df = df.apply(lambda x: [x['p'],x['q']] if x['p']>x['q'] else [x['q'],x['p']],axis=1,result_type='expand')
return df
res = pd.DataFrame(
index=[20, 200, 2000, 20000, 200000],
columns='df_where agg_maxmin np_flip lambda_x'.split(),
dtype=float
)
for i in res.index:
d = pd.concat([df]*i)
for j in res.columns:
stmt = '{}(d)'.format(j)
setp = 'from __main__ import d, {}'.format(j)
print(stmt, d.shape)
res.at[i, j] = timeit(stmt, setp, number=1)
res.plot(loglog=True);

TA貢獻1853條經(jīng)驗 獲得超18個贊
用于numpy.sort按水平軸升序排序,然后翻轉(zhuǎn)數(shù)組axis=1:
df = pd.DataFrame(np.flip(np.sort(df), axis=1), columns=df.columns)
p q
0 0.5 0.5
1 0.6 0.4
2 0.7 0.3
3 0.6 0.4
4 0.9 0.1

TA貢獻1789條經(jīng)驗 獲得超10個贊
使用agg
,傳遞函數(shù)列表(max
和min
)并指定axis=1
將這些函數(shù)按行應(yīng)用于列。
df[['p', 'q']] = df[['p', 'q']].agg([max, min], axis=1)
>>> df
? ? ?p? ? q
0? 0.5? 0.5
1? 0.6? 0.4
2? 0.7? 0.3
3? 0.6? 0.4
4? 0.9? 0.1
簡單的解決方案并不總是最有效的(例如上面的解決方案)。以下解決方案明顯更快。p它屏蔽列小于列的數(shù)據(jù)幀q,然后交換值。
mask = df['p'].lt(df['q'])
df.loc[mask, ['p', 'q']] = df.loc[mask, ['q', 'p']].to_numpy()
>>> df
? ? ?p? ? q
0? 0.5? 0.5
1? 0.6? 0.4
2? 0.7? 0.3
3? 0.6? 0.4
4? 0.9? 0.1

TA貢獻1829條經(jīng)驗 獲得超7個贊
您可以使用應(yīng)用功能:
df[['p','q']] = df.apply(lambda x: [x['p'],x['q']] if x['p']>x['q'] else [x['q'],x['p']],axis=1,result_type='expand' )
添加回答
舉報