在 pandas.DataFrame 的多个列上使用 numpy.unique
Using numpy.unique on multiple columns of a pandas.DataFrame
我希望使用 numpy.unique
获取 pandas.DataFrame
的两列的反向唯一索引。
我知道如何在一列上使用它:
u, rev = numpy.unique(df[col], return_inverse=True)
但我想在多个列上使用它。例如,如果 df
看起来像:
0 1
0 1 1
1 1 2
2 2 1
3 2 1
4 3 1
那么我想得到反向索引:
[0,1,2,2,3]
我认为您可以将列转换为 strings
然后 sum
:
u, rev = np.unique(df.astype(str).values.sum(axis=1), return_inverse=True)
print (rev)
[0 1 2 2 3]
如前所述(谢谢),这很危险。
另一个解决方案是将行转换为 tuples
:
u, rev = np.unique(df.apply(tuple, axis=1), return_inverse=True)
print (rev)
[0 1 2 2 3]
方法 #1
这是一种将每一行转换为标量的 NumPy 方法,每一行都将每一行视为二维(对于 2 列数据)网格上的一个索引元组 -
def unique_return_inverse_2D(a): # a is array
a1D = a.dot(np.append((a.max(0)+1)[:0:-1].cumprod()[::-1],1))
return np.unique(a1D, return_inverse=1)[1]
如果数据中有负数,我们也需要使用 min
来获取这些标量。因此,在这种情况下,请使用 a.max(0) - a.min(0) + 1
代替 a.max(0) + 1
.
方法 #2
这是另一个基于 NumPy 视图的解决方案,其重点是受 -
启发的性能
def unique_return_inverse_2D_viewbased(a): # a is array
a = np.ascontiguousarray(a)
void_dt = np.dtype((np.void, a.dtype.itemsize * np.prod(a.shape[1:])))
return np.unique(a.view(void_dt).ravel(), return_inverse=1)[1]
样品运行 -
In [209]: df
Out[209]:
0 1 2 3
0 21 7 31 69
1 62 75 22 62 # ----|
2 16 46 9 31 # |==> Identical rows, so must have same IDs
3 62 75 22 62 # ----|
4 24 12 88 15
In [210]: unique_return_inverse_2D(df.values)
Out[210]: array([1, 3, 0, 3, 2])
In [211]: unique_return_inverse_2D_viewbased(df.values)
Out[211]: array([1, 3, 0, 3, 2])
我希望使用 numpy.unique
获取 pandas.DataFrame
的两列的反向唯一索引。
我知道如何在一列上使用它:
u, rev = numpy.unique(df[col], return_inverse=True)
但我想在多个列上使用它。例如,如果 df
看起来像:
0 1
0 1 1
1 1 2
2 2 1
3 2 1
4 3 1
那么我想得到反向索引:
[0,1,2,2,3]
我认为您可以将列转换为 strings
然后 sum
:
u, rev = np.unique(df.astype(str).values.sum(axis=1), return_inverse=True)
print (rev)
[0 1 2 2 3]
如前所述
另一个解决方案是将行转换为 tuples
:
u, rev = np.unique(df.apply(tuple, axis=1), return_inverse=True)
print (rev)
[0 1 2 2 3]
方法 #1
这是一种将每一行转换为标量的 NumPy 方法,每一行都将每一行视为二维(对于 2 列数据)网格上的一个索引元组 -
def unique_return_inverse_2D(a): # a is array
a1D = a.dot(np.append((a.max(0)+1)[:0:-1].cumprod()[::-1],1))
return np.unique(a1D, return_inverse=1)[1]
如果数据中有负数,我们也需要使用 min
来获取这些标量。因此,在这种情况下,请使用 a.max(0) - a.min(0) + 1
代替 a.max(0) + 1
.
方法 #2
这是另一个基于 NumPy 视图的解决方案,其重点是受
def unique_return_inverse_2D_viewbased(a): # a is array
a = np.ascontiguousarray(a)
void_dt = np.dtype((np.void, a.dtype.itemsize * np.prod(a.shape[1:])))
return np.unique(a.view(void_dt).ravel(), return_inverse=1)[1]
样品运行 -
In [209]: df
Out[209]:
0 1 2 3
0 21 7 31 69
1 62 75 22 62 # ----|
2 16 46 9 31 # |==> Identical rows, so must have same IDs
3 62 75 22 62 # ----|
4 24 12 88 15
In [210]: unique_return_inverse_2D(df.values)
Out[210]: array([1, 3, 0, 3, 2])
In [211]: unique_return_inverse_2D_viewbased(df.values)
Out[211]: array([1, 3, 0, 3, 2])