Python 如何记录「;“最少发生”;数据帧中的项目?

Python 如何记录「;“最少发生”;数据帧中的项目?,python,pandas,Python,Pandas,我有以下数据框,只有三列: import pandas pd dict_example = {'col1':['A', 'A', 'A', 'A', 'A'], 'col2':['A', 'B', 'A', 'B', 'A'], 'col3':['A', 'A', 'A', 'C', 'B']} df = pd.DataFrame(dict_example) print(df) col1 col2 col3 0 A A A 1 A B A 2

我有以下数据框,只有三列:

import pandas pd
dict_example = {'col1':['A', 'A', 'A', 'A', 'A'], 
    'col2':['A', 'B', 'A', 'B', 'A'], 'col3':['A', 'A', 'A', 'C', 'B']}

df = pd.DataFrame(dict_example)

print(df)
  col1 col2 col3
0    A    A    A
1    A    B    A
2    A    A    A
3    A    B    C
4    A    A    B
对于包含不同元素的行,我尝试编写一个函数,返回“少数”元素的列名

例如,在第1行中,有2个A和1个B。如果只有一个B,我认为这是“少数”。如果所有元素都相同,自然就没有少数(或多数)。但是,如果每个列具有不同的值,那么我认为这些列是少数。p> 以下是我的想法:

  col1 col2 col3   min
0    A    A    A   []
1    A    B    A   ['col2']
2    A    A    A   []
3    A    B    C   ['col1', 'col2', 'col3']
4    A    A    B   ['col3']
我不知道如何有效地计算这个

使用
pandas.DataFrame.mode()
或可以在如下列表中找到最大项目数,可以直接查找最大项目数:

lst = ['A', 'B', 'A']
max(lst,key=lst.count)

但我不确定如何才能找到出现最少的项目

这个解决方案并不简单-但是如果没有
apply
,我想不出一个
pandas
本机解决方案,而且
numpy
如果没有下面针对内行唯一性和值计数的复数技巧,似乎也没有多少帮助


如果您不打算添加此
min
列,我们可以使用一些
numpy
技巧来
nan
排除非最少出现的条目。首先,给定您的数据帧,我们可以创建一个整数的numpy数组来提供帮助

v=pd.factorize(df.stack())[0]。重塑(df.shape)

(应该更快,因为堆栈不是必需的)

然后,对numpy行
unique
元素使用一些技巧(使用复数将元素标记为每行中唯一的元素,找到出现最少的元素,并在其中屏蔽它们)。这种方法主要是从用户使用的几个方面

给予

  col1 col2 col3
0  NaN  NaN  NaN
1  NaN    B  NaN
2  NaN  NaN  NaN
3    A    B    C
4  NaN  NaN    B


希望这能以一种高效的方式实现您想要的(比如说,如果这个数据帧相当大的话)。如果有一种更快的方法来实现第一行(不使用
堆栈
),我可以想象,即使对于非常大的数据帧,这也相当快

谢谢!它是一个大数据帧,因此应该执行此操作。我来试一试。事实上,看起来我发现了一种情况,它没有按预期工作。我有一行4个a和2个B,这表明没有“少数”字符。也许我可以和你共享数据?是的@EB2127我可以看看我不知道如何共享数据帧。这一行是A,A,C,C,A,A
def make_mask(a):
    weight = 1j*np.linspace(0, a.shape[1], a.shape[0], endpoint=False)
    b = a + weight[:, np.newaxis]
    u, ind, c = np.unique(b, return_index=True, return_counts=True)
    b = np.full_like(a, np.nan, dtype=float)
    np.put(b, ind, c)
    m = np.nanmin(b, axis=1)
    # remove only uniques
    b[(~np.isnan(b)).sum(axis=1) == 1, :] = np.nan
    # remove lower uniques
    b[~(b == m.reshape(-1, 1))] = np.nan
    return b

m = np.isnan(make_mask(v))
df[m] = np.nan
  col1 col2 col3
0  NaN  NaN  NaN
1  NaN    B  NaN
2  NaN  NaN  NaN
3    A    B    C
4  NaN  NaN    B