【发布时间】:2022-11-11 20:23:23
【问题描述】:
我有一个pandasDataFrame,列中有A、B、C 和D 中的值,并且想为每一行确定第一个和最后一个非零列。但是所有行的元素顺序并不相同。它由item_0、item_1 和item_2 列确定。
虽然我可以通过对每一行应用一个函数来轻松地做到这一点,但这对于我的DataFrame 来说变得非常慢。有没有一种优雅的、更 Pythonic/pandasy 的方式来做到这一点?
输入:
A B C D item_0 item_1 item_2
0 1 2 0 0 A B C
1 0 1 1 0 A B C
2 1 0 1 0 A B C
3 0 2 0 0 D A B
4 1 1 0 1 D A B
5 0 0 0 1 D A B
预期输出:
A B C D item_0 item_1 item_2 first last
0 1 2 0 0 A B C A B
1 0 1 1 0 A B C B C
2 1 0 1 0 A B C A C
3 0 2 0 0 D A B B B
4 1 1 0 1 D A B D B
5 0 0 0 1 D A B D D
更新:这是apply 的当前代码
import pandas as pd
def first_and_last_for_row(row):
reference_list = row[["item_0", "item_1", "item_2"]].tolist()
list_to_sort = (
row[["A", "B", "C", "D"]].index[row[["A", "B", "C", "D"]] > 0].tolist()
)
ordered_list = [l for l in reference_list if l in list_to_sort]
if len(ordered_list) == 0:
return None, None
else:
return ordered_list[0], ordered_list[-1]
df = pd.DataFrame(
{
"A": [1, 0, 1, 0, 1, 0],
"B": [2, 1, 0, 2, 1, 0],
"C": [0, 1, 1, 0, 0, 0],
"D": [0, 0, 0, 0, 1, 1],
"item_0": ["A", "A", "A", "D", "D", "D"],
"item_1": ["B", "B", "B", "A", "A", "A"],
"item_2": ["C", "C", "C", "B", "B", "B"],
}
)
df[["first", "last"]] = df.apply(first_and_last_for_row, axis=1, result_type="expand")
【问题讨论】:
-
您能否逐行分享您当前正在使用的代码/功能?另外,“慢”对您意味着什么?你有时间/内存限制吗?数据框本身有多大?
-
所选列中是否始终存在非零?否则会发生什么?
-
@FBruzzesi 我更新了帖子以包含当前代码。 “慢”意味着约 5 分钟约 600 000 行。我预计未来的行数会增长。我没有严格的时间限制,但目前它正处于令人讨厌且值得花时间改进的地步。
-
@mozway 可以(并且是)所有零行。在这种情况下,第一个和最后一个元素可以被视为
nan。但是忽略这种特殊情况很好,因为我可以相应地过滤 DataFrame。