如何在 Pandas 中选择行范围?

Posted

技术标签:

【中文标题】如何在 Pandas 中选择行范围?【英文标题】:How to select range of rows in Pandas? 【发布时间】:2018-09-27 00:10:23 【问题描述】:

我创建了一个具有一系列特征的数据框。我想创建一个新列来选择两个特定行之间的所有行(这将是输入)。

说dataframe如下:

data = 'currency': ['Euro', 'Euro', 'Euro', 'Dollar', 'Dollar', 'Yen',
                     'Yen', 'Yen', 'Pound', 'Pound', 'Pound, 'Pesos',
                     'Pesos'], 
    'cost': [34, 67, 32, 29, 48, 123, 23, 45, 78, 86, 23, 45, 67]
df = pd.DataFrame(data, columns = ['currency', 'cost'])
df

df 表:

我想添加一个在满足条件时分配 1 的新列。就我而言,条件是两种特定货币之间的所有行。例如,假设我想要“美元”和“英镑”之间的所有货币。我的猜测是我必须创建一个掩码并将其用作条件,即选择第一个“美元”行和最后一个“英镑”行之间的所有行(即第 3-10 行)。

我在创建该掩码时遇到了问题,因为货币是按字母顺序选择的:

mask = (df['currency'] >= 'Dollar') & (df['currency'] <= 'Pound')

上面创建了一个新列,其中包含所有货币的 T,但“日元”除外。我可以看到为什么上述方法失败了,但想不出一种方法来做我想做的事。

注意:相同的货币名称将分组出现,例如“磅”不能在第 4-5 行和第 8-10 行中。

【问题讨论】:

能否请您添加预期的输出。 很好的问题。只是对您的快速和理解反应表示一点赞赏! 【参考方案1】:

也适用于重复索引的通用解决方案:

a = df['currency'].eq('Dollar').cumsum()
b = df['currency'].eq('Pound').iloc[::-1].cumsum()
df['new'] = a.mul(b).clip_upper(1)

唯一索引的替代方法:

a = df['currency'].eq('Dollar').idxmax()
b = df['currency'].eq('Pound').iloc[::-1].idxmax()
df['new'] = 0
df.loc[a:b, 'new'] = 1

print (df)
   currency  cost  new
0      Euro    34    0
1      Euro    67    0
2      Euro    32    0
3    Dollar    29    1
4    Dollar    48    1
5       Yen   123    1
6       Yen    23    1
7       Yen    45    1
8     Pound    78    1
9     Pound    86    1
10    Pound    23    1
11    Pesos    45    0
12    Pesos    67    0

解释:

    先比较Series.eq==相同的地方 获取cumsum [::-1] 的第二个条件反向掩码 将mul 相乘并将非0 替换为1clip_upper

第二个解决方案使用idxmax 作为第一个索引值并通过loc 设置1

【讨论】:

【参考方案2】:

在逻辑或上使用 Numpy 的累加

cumor = np.logical_or.accumulate

c = df.currency.values
d = c == 'Dollar'
p = c == 'Pound'

df.assign(new=(cumor(d) & cumor(p[::-1])[::-1]).astype(np.uint))

   currency  cost  new
0      Euro    34    0
1      Euro    67    0
2      Euro    32    0
3    Dollar    29    1
4    Dollar    48    1
5       Yen   123    1
6       Yen    23    1
7       Yen    45    1
8     Pound    78    1
9     Pound    86    1
10    Pound    23    1
11    Pesos    45    0
12    Pesos    67    0

【讨论】:

以上是关于如何在 Pandas 中选择行范围?的主要内容,如果未能解决你的问题,请参考以下文章

如何创建一个新的 pandas 列,该列是索引范围中每个值的列表,不包括行值

从表中随机选择行 - Python Pandas 读取 SQL

从表中随机选择行 - Python Pandas Read SQL

pandas如何选择14到20之间的行

根据条件在Pandas DataFrame中选择行

通过 pandas.read_excel 在标题后跳过行范围