Skip to main content
 首页 » 编程设计

python之Pandas 无需迭代即可选择一致的更改

2025年05月04日11lidabo

我有一个看起来像这样的数据框:

In [9]: d = pd.DataFrame({'place': ['home', 'home', 'home', 'home', 'office', 'office', 'office', 'home', 'office', 'home', 'office', 'home', 'office', 'home'], 'person': ['a', 'a', 'a', 'a', 'a', 'a', 'a', 'b', 'b', 'c', 'c', 'c', 'c', 'c'], 'other_stuff': ['f', 'g', 'd', 'q', 'w', 'r', 's', 't', 'u', 'v', 'w', 'l', 'm', 'n']}) 
 
 
 
In [7]: d 
      place  other_stuff person 
 0     home           f      a 
 1     home           g      a 
 2     home           d      a 
 3     home           q      a 
 4   office           w      a 
 5   office           r      a 
 6   office           s      a 
 7     home           t      b 
 8   office           u      b 
 9     home           v      c 
 10  office           w      c 
 11    home           l      c 
 12  office           m      c 
 13    home           n      c 

我的数据中只有两个 place 类别:home 和 office。我想选择此数据框的行,这些行与 place 列中具有“永久转换”的所有 person 相对应。即,我只想选择在其 place 中发生变化并且不会变回原样的 persons。

在此示例数据框中,我想选择对应于 person a 和 person b 的所有行,但不选择 person c。期望的输出是:

      place  other_stuff person 
 0     home           f      a 
 1     home           g      a 
 2     home           d      a 
 3     home           q      a 
 4   office           w      a 
 5   office           r      a 
 6   office           s      a 
 7     home           t      b 
 8   office           u      b 

我打算在person列上groupby,然后写一个函数apply到每组观察值。我的数据框有大约 6000 万行和 700,000 个独特的 persons,所以我不想使用任何类型的迭代。 我不确定如何编写一个函数来选择正确的行,而无需遍历每组 person 观察结果。

请您参考如下方法:

使用groupby shift,根据位置变化创建每个人的子组,如果变化超过两次,那么我们不应该将整个组保留在新的数据框

s=df.groupby('person').apply(lambda   x : (x['place'].shift()!=x['place']).cumsum().nunique()) 
 
df.loc[df.person.isin(s[s<=2].index)] 
 
 
 
    place other_stuff person 
0    home           f      a 
1    home           g      a 
2    home           d      a 
3    home           q      a 
4  office           w      a 
5  office           r      a 
6  office           s      a 
7    home           t      b 
8  office           u      b