Python 如何按不在数据帧中的数组对数据帧进行排序
我已经在不同的背景下回答了好几次这个问题,我意识到在任何地方都没有一个好的规范化方法 因此,要设置一个简单的问题: 问题 问题: 如何按列“Python 如何按不在数据帧中的数组对数据帧进行排序,python,sorting,pandas,numpy,Python,Sorting,Pandas,Numpy,我已经在不同的背景下回答了好几次这个问题,我意识到在任何地方都没有一个好的规范化方法 因此,要设置一个简单的问题: 问题 问题: 如何按列“A”和“'B”的乘积排序? 这里有一种方法,我在数据框中添加一个临时列,使用它对值进行排序,然后将其删除 df.assign(P=df.prod(1)).sort_values('P').drop('P', 1) A B 0 0 1 1 1 2 2 2 1 4 4 1 3 3 2 5 5 2 是否有更好、更简洁、更清晰、
A”和“'B”的乘积排序?
这里有一种方法,我在数据框中添加一个临时列,使用它对值进行排序,然后将其删除
df.assign(P=df.prod(1)).sort_values('P').drop('P', 1)
A B
0 0 1
1 1 2
2 2 1
4 4 1
3 3 2
5 5 2
是否有更好、更简洁、更清晰、更一致的方法;DR
iloc
+argsort
我们可以使用一个有序位置数组并返回按这些位置重新排序的数据帧来实现这一点
借助的强大功能,我们可以对指定顺序的任何数组进行排序
现在,我们需要做的就是确定一种获得这种排序的方法。事实证明,有一个名为的方法正是这样做的。通过将结果传递到,我们可以整理数据帧
例1
使用上面指定的问题
结果同上
A B
0 0 1
1 1 2
2 2 1
4 4 1
3 3 2
5 5 2
那是为了简单。如果性能是一个问题,我们可以进一步关注numpy
v = df.values
a = v.prod(1).argsort()
pd.DataFrame(v[a], df.index[a], df.columns)
这些解决方案有多快
我们可以看到,pd\u ext\u sort
是最简洁的,但其伸缩性不如其他方法。
np\u ext\u sort
以牺牲透明度为代价提供最佳性能。尽管如此,我认为现在发生的事情仍然很清楚
反向测试设置
例2
假设我有一列负值和正值。我想通过增加数量来排序。。。不过,我希望先看底片
假设我有数据帧df
df = pd.DataFrame(dict(A=range(-2, 3)))
print(df)
A
0 -2
1 -1
2 0
3 1
4 2
我将再次设置3个版本。这次我将使用np.lexsort
,它返回与argsort
相同类型的数组。也就是说,我可以用它来重新排序数据帧
注意事项:np.lexsort
首先按列表中的最后一个数组排序\舒格
所有这些都会回来
A
1 -1
0 -2
2 0
3 1
4 2
这次有多快
在本例中,pd\u ext\u sort
和np\u ext\u sort
的性能都优于add\u drop
反向测试设置
def add_drop():
return df.assign(P=df.prod(1)).sort_values('P').drop('P', 1)
def pd_ext_sort():
return df.iloc[df.prod(1).argsort()]
def np_ext_sort():
v = df.values
a = v.prod(1).argsort()
return pd.DataFrame(v[a], df.index[a], df.columns)
results = pd.DataFrame(
index=pd.Index([10, 100, 1000, 10000], name='Size'),
columns=pd.Index(['add_drop', 'pd_ext_sort', 'np_ext_sort'], name='method')
)
for i in results.index:
df = pd.DataFrame(np.random.rand(i, 2), columns=['A', 'B'])
for j in results.columns:
stmt = '{}()'.format(j)
setup = 'from __main__ import df, {}'.format(j)
results.set_value(i, j, timeit(stmt, setup, number=100))
results.plot()
df = pd.DataFrame(dict(A=range(-2, 3)))
print(df)
A
0 -2
1 -1
2 0
3 1
4 2
def add_drop():
return df.assign(P=df.A >= 0, M=df.A.abs()).sort_values(['P', 'M']).drop(['P', 'M'], 1)
def pd_ext_sort():
v = df.A.values
return df.iloc[np.lexsort([np.abs(v), v >= 0])]
def np_ext_sort():
v = df.A.values
a = np.lexsort([np.abs(v), v >= 0])
return pd.DataFrame(v[a, None], df.index[a], df.columns)
A
1 -1
0 -2
2 0
3 1
4 2
results = pd.DataFrame(
index=pd.Index([10, 100, 1000, 10000], name='Size'),
columns=pd.Index(['add_drop', 'pd_ext_sort', 'np_ext_sort'], name='method')
)
for i in results.index:
df = pd.DataFrame(np.random.randn(i, 1), columns=['A'])
for j in results.columns:
stmt = '{}()'.format(j)
setup = 'from __main__ import df, {}'.format(j)
results.set_value(i, j, timeit(stmt, setup, number=100))
results.plot(figsize=(15, 6))