如何基于熊猫中的另一列数组对一列数组排序?

时间:2019-01-10 17:49:04

标签: python pandas dataframe

我有一个这样的数据框:

df1= pd.DataFrame({
    'col1': [np.asarray([1,4,3,2]), np.asarray([9,10,7,5]), np.asarray([100,120,10,22])],
    'col2': [np.asarray([0,1,4,5]), np.asarray([100,101,102,103]), np.asarray([10,11,12,13])]
})

df1
                 col1                  col2
0        [1, 4, 3, 2]          [0, 1, 4, 5]
1       [9, 10, 7, 5]  [100, 101, 102, 103]
2  [100, 120, 10, 22]      [10, 11, 12, 13]

我想根据第1列中的数组的值对第2列中的数组的值进行排序。

这是我的解决方法:

sort_idx = df1['col1'].apply(np.argsort).values
for rowidxval, (index, row) in enumerate(df1.iterrows()):
    df1['col1'][index] = df1['col1'][index][sort_idx[rowidxval]]
    df1['col2'][index] = df1['col2'][index][sort_idx[rowidxval]]

是否有一种优雅的,pythonic的方法来代替按行对数据框进行强行排序?如果我想根据第1列中的值对一个以上的列进行重新排序怎么办?

3 个答案:

答案 0 :(得分:5)

从不建议使用列中的列表(混合dtypes和可变dtypes会导致瓶颈和代码性能降低),但是您可以使用列表理解来使其尽可能快:

df['col2'] = [np.array(y)[np.argsort(x)] for x, y in zip(df.col1, df.col2)]
df

                 col1                  col2
0        [1, 4, 3, 2]          [0, 5, 4, 1]
1       [9, 10, 7, 5]  [103, 102, 100, 101]
2  [100, 120, 10, 22]      [12, 13, 10, 11]

如果它们都是数组,则解决方案可以简化:

df['col2'] = [y[x.argsort()] for x, y in zip(df.col1, df.col2)]
df

                 col1                  col2
0        [1, 4, 3, 2]          [0, 5, 4, 1]
1       [9, 10, 7, 5]  [103, 102, 100, 101]
2  [100, 120, 10, 22]      [12, 13, 10, 11]

有关性能相关问题的更多信息,请参见For loops with pandas - When should I care?中有关“混合dtypes”的部分。

答案 1 :(得分:3)

使用循环

[[z for _,z in sorted(zip(x,y))] for x, y in zip(df1.col1, df1.col2)]
Out[250]: [[0, 5, 4, 1], [103, 102, 100, 101], [12, 13, 10, 11]]

#df1.col2=[[z for _,z in sorted(zip(x,y))] for x, y in zip(df1.col1, df1.col2)]

答案 2 :(得分:0)

尝试并避免在系列中使用NumPy数组。这样的数据结构将不支持矢量化计算。由于在这种情况下,所有数组都具有相同的大小,因此您可以轻松地将它们分成多列:

def insert(title,author,year,isbn):
    con= mysql.connector.connect(host="localhost",user="root",passwd="junai2104",database="book")
    cur=con.cursor()
    sql_statement='INSERT INTO book(title,author,year,isbn) VALUES ('
    sql_statement = sql_statement + "'" + title + "','" + author + "'," + year + "," + isbn + ")"
    cur.execute(sql_statement)
    con.commit()
    con.close()
insert('test2','test2',1234,13525545)