2016-10-22 60 views
3

問題
「東風有兩列,但有時充斥着相同的價值觀,我們需要將它們重新保存成兩列,但在字母。爲了」
的Python:熊貓:兩列相同的值,按字母順序排序和存儲

語境
我們有熊貓DF這樣的:

df = pd.DataFrame([{"name_A": "john", "name_B": "mac"}, {"name_A": "mac", "name_B": "john"}]) 

像這樣:

name_A | name_B 
john | mac 
mac | john 
Trump | Clinton 


所需的輸出

name_A | name_B | restated_A | restated_B 
john | mac  | john  | mac 
mac | john | john  | mac 
trump | clinton | clinton | trump 

在的話,我們希望有列的值name_Aname_Brestated_A按照字母順序排序,並restated_B

到目前爲止已經試過
一堆lambdas但cou ldn't得到它的工作

規格
的Python:3.5.2
熊貓:0.18.1

+0

請考慮[接受答案之一(HTTPS://元。stackexchange.com/questions/5234/how-does-accepting-an-answer-work)如果它解決了你的問題。 – user7337271

回答

2

只需發送df.values到列表和排序該列表中的每一行。然後相應地重新分配對中的元素。

>>> df = pd.DataFrame([{"name_A": "john", "name_B": "mac"}, {"name_A": "mac", "name_B": "john"}]) 
>>> restated_values = [sorted(pair) for pair in df.values.tolist()] 
>>> restated_values 
[['john', 'mac'], ['john', 'mac']] 
>>> df['restated_A'] = [pair[0] for pair in restated_values] 
>>> df 
    name_A name_B restated_A 
0 john mac  john 
1 mac john  john 
>>> df['restated_b'] = [pair[1] for pair in restated_values] 
>>> df 
    name_A name_B restated_A restated_b 
0 john mac  john  mac 
1 mac john  john  mac 

或者,你可以做到這一點,利用dict和新pandas.DataFrame對象:

>>> df = pd.DataFrame([{"name_A": "john", "name_B": "mac"}, {"name_A": "mac", "name_B": "john"}]) 
>>> restated_values = [sorted(pair) for pair in df.values.tolist()] 
>>> restated_values 
[['john', 'mac'], ['john', 'mac']] 
>>> new_col_rows = {'restated_A': [pair[0] for pair in restated_values], 'restated_B': [pair[1] for pair in restated_values]} 
>>> new_col_rows 
{'restated_A': ['john', 'john'], 'restated_B': ['mac', 'mac']} 
>>> new_df = pd.DataFrame(new_col_rows) 
>>> new_df 
    restated_A restated_B 
0  john  mac 
1  john  mac 
>>> df = df.join(new_df) 
>>> df 
    name_A name_B restated_A restated_B 
0 john mac  john  mac 
1 mac john  john  mac 
4

作爲替代量化的解決方案,你可以使用numpy.minimum()numpy.maximum()

import numpy as np 
df['restart_A'] = np.minimum(df['name_A'], df['name_B']) 
df['restart_B'] = np.maximum(df['name_A'], df['name_B']) 

enter image description here

或者使用apply方法:

df[['restated_A', 'restated_B']] = df.apply(lambda r: sorted(r), axis = 1) 

enter image description here

-1

您可以使用命令 「到位」 進行排序NumPy的sort()方法:

In [57]: df 
Out[57]: 
    name_A name_B 
0 john  mac 
1 mac  john 
2 Trump Clinton 

In [58]: df.values.sort(axis=1) 

In [59]: df 
Out[59]: 
    name_A name_B 
0  john mac 
1  john mac 
2 Clinton Trump 

定時對30K行DF:

In [69]: %%timeit 
    ...: big = pd.concat([df.copy()] * 10**4, ignore_index=True) 
    ...: big.values.sort(axis=1) 
    ...: 
1 loop, best of 3: 2.25 s per loop 

In [70]: %%timeit 
    ...: big = pd.concat([df.copy()] * 10**4, ignore_index=True) 
    ...: big.apply(lambda r: sorted(r), axis = 1) 
    ...: 
1 loop, best of 3: 15.9 s per loop 

In [71]: %%timeit 
    ...: big = pd.concat([df.copy()] * 10**4, ignore_index=True) 
    ...: pd.DataFrame([sorted(pair) for pair in big.values.tolist()], columns=df.columns) 
    ...: 
1 loop, best of 3: 2.29 s per loop 

定時針對300K行DF:

In [73]: %%timeit 
    ...: big = pd.concat([df.copy()] * 10**5, ignore_index=True) 
    ...: big.values.sort(axis=1) 
    ...: 
1 loop, best of 3: 23 s per loop 

In [74]: %%timeit 
    ...: big = pd.concat([df.copy()] * 10**5, ignore_index=True) 
    ...: big.apply(lambda r: sorted(r), axis = 1) 
    ...: 
1 loop, best of 3: 2min 39s per loop 

In [75]: %%timeit 
    ...: big = pd.concat([df.copy()] * 10**5, ignore_index=True) 
    ...: pd.DataFrame([sorted(pair) for pair in big.values.tolist()], columns=df.columns) 
    ...: 
1 loop, best of 3: 23.4 s per loop