【问题标题】:Identify varying rows in pandas dataframe识别熊猫数据框中的不同行
【发布时间】:2022-01-23 19:50:23
【问题描述】:

我有一个数据框:

ColA    ColB    ColC    
a       0        1     
b       3        3     
c       1        1
a       0        1
a       1        2
b       3        3

在根据列中的值进行过滤时,我需要识别具有不同值的每一行。示例:当我在 ColA 中过滤值为“a”的数据框时,第 5 行在 ColB 和 ColC 中具有不同的值。

我试过了

df['result']=df['ColA'].ne(df['ColA'].shift().bfill()).astype(int)

导致:

ColA ColB ColC result
a 0 1 0
b 3 3 1
c 1 1 1
a 0 1 1
a 1 2 1
b 3 3 1

我需要的是(过滤值'a'应该识别其他列中具有不同值的行):

ColA ColB ColC result
a 0 1 0
b 3 3 1
c 1 1 1
a 0 1 0
a 1 2 1
b 3 3 1

如果我使用 groupby 方法:

df.groupby(df.columns.tolist())['ColA'].nunique()

它仅适用于具有几种数据类型的小型数据帧。

【问题讨论】:

  • 你为什么不能只做df['result'] = df['ColB'] == df['ColC']?我不明白你在这里用 ColA 过滤是什么意思。
  • 为什么 b、3、3 行的结果列是 1?据我了解,它应该是 0,因为它是 ColA 中带有 b 的第一行?
  • @MayurKr.Garg 在这里,单行中的值应该一起考虑。所以,应该比较行中发生的变化。示例:第 4 行具有与第 1 行相同的值。但是第 5 行有不同的值,因此结果列中的值为 1。
  • @Ben.T 你是对的。这是我的错误。
  • 为什么第一行的结果是0,第三行的结果是1?

标签: python pandas dataframe rows


【解决方案1】:

如果我理解正确,您可以drop_duplicates,然后使用groupbycumcount 创建结果列,以获取每个组的每个唯一行的标识符。

print(df.drop_duplicates(subset=['ColA','ColB','ColC'])
        .assign(result=lambda x: x.groupby('ColA').cumcount()))
#   ColA  ColB  ColC  result
# 0    a     0     1       0
# 1    b     3     3       0
# 2    c     1     1       0
# 4    a     1     2       1

如您所见,您在原始 df 中“缺少行”,因此 merge 将其返回到 df。

df = (
    df.merge(df.drop_duplicates(subset=['ColA','ColB','ColC'])
               .assign(result=lambda x: x.groupby('ColA').cumcount()), 
             how='left')
)
print(df)
#   ColA  ColB  ColC  result
# 0    a     0     1       0
# 1    b     3     3       0
# 2    c     1     1       0
# 3    a     0     1       0
# 4    a     1     2       1
# 5    b     3     3       0

【讨论】:

  • 为什么(c 1 1)是0而不是1? (这个问题对我来说不是很清楚......)
  • @Corralien 我理解他们想为每个唯一行(ColB-ColC)的每个组 ColA 创建一个标识符,所以 c 1 1 是 ColA 中 c 的第一行,它给出 0。我可以看看你为什么想出你的答案:)
【解决方案2】:

最快的方法是通过drop_duplicates(keep=False) 删除重复的行并根据索引创建result 列。

data = {
    'ColA': ['a', 'b', 'c', 'a', 'a', 'b'], 
    'ColB': [0, 3, 1, 0, 1, 3],
    'ColC': [1, 3, 1, 1, 2, 3]
}
df = pd.DataFrame(data)

unique_rows = df.drop_duplicates(keep=False)
df['result'] = df.index.isin(unique_rows.index).astype(int)

print(df)

【讨论】:

    【解决方案3】:

    如果您只想拥有一个唯一的 ID,请在整个数据框上使用 pd.factorize,而不使用 groupby

    df['result'] = pd.factorize(df.agg(tuple, axis=1))[0]
    print(df)
    
    # Output
      ColA  ColB  ColC  result
    0    a     0     1       0
    1    b     3     3       1
    2    c     1     1       2
    3    a     0     1       0
    4    a     1     2       3
    5    b     3     3       1
    

    你可以使用duplicated:

    df['result'] = (~df.duplicated(keep=False)).astype(int)
    print(df)
    
    # Output
      ColA  ColB  ColC  result
    0    a     0     1       0
    1    b     3     3       0
    2    c     1     1       1
    3    a     0     1       0
    4    a     1     2       1
    5    b     3     3       0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-23
      • 1970-01-01
      • 2019-08-04
      • 2019-08-19
      • 1970-01-01
      相关资源
      最近更新 更多