如何使用 Pandas 在 Python 中基于同一行中的另一个单元格设置单元格值

Posted

技术标签:

【中文标题】如何使用 Pandas 在 Python 中基于同一行中的另一个单元格设置单元格值【英文标题】:How do I set a cell value based on another cell in same row in Python Using Pandas 【发布时间】:2021-12-27 05:55:57 【问题描述】:

我正在研究 Python 和 Pandas 库并尝试一些基础知识,但在文档中迷失了方向。

我有一个Pandas DataFrame

A    B    C    D
1    2    3    4
3    4    1    7
6    9    0    1

... 其他 10k+ 行。

我现在想添加一个列“E”,如果“D”的值位于整个列的前 10%,则该列应为 True/False

我尝试的一种方法是按“D”列降序排序,然后更新前 10% 的行,这样我可以排序但还没有弄清楚如何更新前 10% 的行

这种方式也会改变原来的顺序,这是不可取的。

 df = df.sort_values('D',ascending=False)
 df.iloc[:0, :(df.shape[0]-1)/10, 5] = value    --- this doesn't work.

只是检查是否有办法在不排序的情况下实现这一点?如果没有,我如何更新前 10% 的行(如果它们已排序)?

谢谢

【问题讨论】:

【参考方案1】:

如果需要 top10 值而不使用重复排序,请使用 np.argsort:

np.random.seed(2021)

df = pd.DataFrame(np.random.randint(30, size=(20, 5)), columns=list('ABCDE'))

n = 10
N = int(len(df.index)*(n/100))
print (N)
2

df['mask'] = np.argsort(np.argsort(-df['E'].to_numpy())) < N
print (df)
     A   B   C   D   E   mask
0   20  21  25   0  13  False
1   22  12  27  29  21   True
2   29  24  12  22   6  False
3    6   6   1   5   7  False
4    1  14   1  28   5  False
5   26   2  16   3  17  False
6   16  18  22  27  20  False
7   29  24   5  17   6  False
8   10  14   7  21   6  False
9    9  21  22  25  18  False
10  10   4  13  10  19  False
11  25  18  26  15   8  False
12  10  12  21  11  19  False
13   1  14  17  25  18  False
14   7  21  19  27  12  False
15  23  19   9   4   9  False
16   7  25   7   7  20  False
17  27  29  11  27  19  False
18  18  14  25  27  18  False
19  21  18  26   0  20   True

如果需要所有 top2 值都可以与 Series.nlargestSeries.isin 进行比较:

df['mask'] = df['E'].isin(df['E'].nlargest(2))
print (df)
     A   B   C   D   E   mask
0   20  21  25   0  13  False
1   22  12  27  29  21   True
2   29  24  12  22   6  False
3    6   6   1   5   7  False
4    1  14   1  28   5  False
5   26   2  16   3  17  False
6   16  18  22  27  20   True
7   29  24   5  17   6  False
8   10  14   7  21   6  False
9    9  21  22  25  18  False
10  10   4  13  10  19  False
11  25  18  26  15   8  False
12  10  12  21  11  19  False
13   1  14  17  25  18  False
14   7  21  19  27  12  False
15  23  19   9   4   9  False
16   7  25   7   7  20   True
17  27  29  11  27  19  False
18  18  14  25  27  18  False
19  21  18  26   0  20   True

【讨论】:

嘿,Jez,感谢您的回复,这有很多值得阅读的内容——您能否简要介绍一下为什么第 19 行是真的但第 16 行和第 6 行是假的? @Muds - 因为它过滤 top2 而没有重复。所以这意味着它选择了top2。如果返回具有重复项的过滤器,则返回 top2 (2Trues) 4Trues - 21+20+20+20. @Muds - 我换句话说 - 列中的重复值?如果是并且仍然需要 10% 的值,那么我的解决方案可以工作。如果值是唯一的,则使用这 3 个解决方案。这取决于需要什么。 是的,这些值不是唯一的,肯定需要前 10%,但不想排除与 90% 行具有相同值的行 太棒了!这有效【参考方案2】:

如果您不想使用内置的quantile。使用排序方法:-

top_10_pc = int(len(df.index) * 0.1)
min_val = min(df.sort_values(by=['D'], ascending=False)[:top_10_pc]['D'])
df['E'] = df['D'] >= min_val

【讨论】:

这按预期工作,但这不是最有效的解决方案。鸣钟的荣誉!

以上是关于如何使用 Pandas 在 Python 中基于同一行中的另一个单元格设置单元格值的主要内容,如果未能解决你的问题,请参考以下文章

python大数据处理模块pandas

基于pandas python的美团某商家的评论销售数据分析(可视化续)

如何基于两个现有列使用 pandas 正确添加新列?

如何在 python Pandas 中执行/解决条件连接?

Python:如何使用 pandas 数据框更新(覆盖)Google BigQuery 表

python使用pandas基于时间条件查询多个oracle数据表