检查数据框列中的所有值是否相同

新手上路,请多包涵

我想快速轻松地检查 counts 的所有列值在数据框中是否相同:

在:

 import pandas as pd

d = {'names': ['Jim', 'Ted', 'Mal', 'Ted'], 'counts': [3, 4, 3, 3]}
pd.DataFrame(data=d)

出去:

   names  counts
0   Jim       3
1   Ted       4
2   Mal       3
3   Ted       3

我只想要一个简单的条件 if all counts = same value 然后 print('True')

有没有快速的方法来做到这一点?

原文由 HelloToEarth 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 604
2 个回答

一种有效的方法是将第一个值与其余值进行比较,并使用 all

 def is_unique(s):
    a = s.to_numpy() # s.values (pandas<0.24)
    return (a[0] == a).all()

is_unique(df['counts'])
# False

尽管最直观的想法可能是计算 unique 值的数量并检查是否只有一个,但这对于我们要尝试做的事情来说会产生不必要的高复杂度。 Numpy 的 np.unique 被 pandas 调用 nunique ,实现了底层数组的排序,其平均复杂度为 O(n·log(n)) ( aesortab-default-6fd45 using).上面的方法是 O(n)

当我们将其应用于整个数据帧时,性能差异变得更加明显(见下文)。


对于整个数据框

如果想要在整个数据帧上执行相同的任务,我们可以通过在 all axis=0 来扩展上述内容:

 def unique_cols(df):
    a = df.to_numpy() # df.values (pandas<0.24)
    return (a[0] == a).all(0)

对于共享示例,我们将得到:

 unique_cols(df)
# array([False, False])


这是上述方法与其他一些方法(例如使用 nunique (对于 pd.Series )相比的基准):

 s_num = pd.Series(np.random.randint(0, 1_000, 1_100_000))

perfplot.show(
    setup=lambda n: s_num.iloc[:int(n)],

    kernels=[
        lambda s: s.nunique() == 1,
        lambda s: is_unique(s)
    ],

    labels=['nunique', 'first_vs_rest'],
    n_range=[2**k for k in range(0, 20)],
    xlabel='N'
)

在此处输入图像描述


以下是 pd.DataFrame 的时间。让我们也与 numba 方法进行比较,这在这里特别有用,因为我们可以在给定列中看到重复值时立即利用快捷方式( _注意:numba 方法仅适用于数值数据_):

 from numba import njit

@njit
def unique_cols_nb(a):
    n_cols = a.shape[1]
    out = np.zeros(n_cols, dtype=np.int32)
    for i in range(n_cols):
        init = a[0, i]
        for j in a[1:, i]:
            if j != init:
                break
        else:
            out[i] = 1
    return out

如果我们比较这三种方法:

 df = pd.DataFrame(np.concatenate([np.random.randint(0, 1_000, (500_000, 200)),
                                  np.zeros((500_000, 10))], axis=1))

perfplot.show(
    setup=lambda n: df.iloc[:int(n),:],

    kernels=[
        lambda df: (df.nunique(0) == 1).values,
        lambda df: unique_cols_nb(df.values).astype(bool),
        lambda df: unique_cols(df)
    ],

    labels=['nunique', 'unique_cols_nb', 'unique_cols'],
    n_range=[2**k for k in range(0, 20)],
    xlabel='N'
)

在此处输入图像描述

原文由 yatu 发布,翻译遵循 CC BY-SA 4.0 许可协议

更新使用 np.unique

 len(np.unique(df.counts))==1
False

或者

len(set(df.counts.tolist()))==1

或者

df.counts.eq(df.counts.iloc[0]).all()
False

或者

df.counts.std()==0
False

原文由 BENY 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题