Pandas: df.loc[-1,col] 有时有效,有时会添加带有 NaN 的额外行

3

我有一个pandas数据框。我正在尝试修改最后一行中name列的值。

我尝试过了。

df.loc[-1,'name'] = "something"

这个可行

现在我用查询从df筛选几行,并将其称为df_query

而我的df_query中的最后一行是

    id  name
21  965 kris

我检查索引-1

df_query.loc['name'].iloc[-1]

它显示“kris”

现在在df_query上我尝试

df_query.loc[-1,'name'] = "something"

它会添加一行而不是用 something 替换 kris

    id  name
21  965.0 kris
-1  NaN "something"

还要将 convers id 从 int 转换为 float。

为什么有时它有效,有时它无效。

后来在搜索后我发现在 https://dev59.com/T18e5IYBdhLWcg3w-Ocn#49510469 找到了答案。

仅使用 iloc[-1, 'a'] 是行不通的,因为 -1 不在索引中。

我无法理解上述原因。

并建议尝试:

df_query.loc[df_query.loc.index[-1],'name'] = "something"

现在它可以工作了。

有人能解释一下发生了什么吗?

2个回答

5
你可以以不同的方式选择name的最后一个值 - 如果使用DataFrame.loc,则如果索引值是唯一的,则使用df.index来获取索引的最后一个值:
df.loc[df.index[-1],'name'] = "something"

或者如果使用 DataFrame.iloc 来获取列名为 name 的位置,可以通过 Index.get_loc 方法实现:

df.iloc[-1,df.columns.get_loc('name')] = "something"

如果使用:

df.loc[-1,'name'] = "something"

如果存在,则使用index = -1尝试设置行,否则创建带有索引-1的新行。问题在于,如果最后一个索引没有-1,而是例如第一个索引,则它将替换第一行而不是最后一行。
因此可以使用以下方法:
#tested last value of index
if df.index[-1] == -1:
    #last value is set
    df.loc[-1,'name'] = "something"

#tested all values if index
elif (df.index == -1).any():
    #some value with -1 is set
    df.loc[-1,'name'] = "something"
else:
    #new row with -1 is created
    df.loc[-1,'name'] = "something"

@Santhosh - 我认为为了避免这个问题,可以使用第一或第二种解决方案。你可以测试-1,但我认为这更加复杂。另外一个问题是,如果使用 df.loc[-1,'name'] = "something" - 如果有 index=-1,它也会替换第一行。 - jezrael
如果数据框只包含一行,则第一行是最后一行我没问题,但我想知道为什么它会创建新行,而不是识别-1。我们如何知道在某些数据框中存在-1索引,而在某些数据框中不存在。 - Santhosh
但我认为它更加复杂。可以解释一下这种复杂性。 - Santhosh
1
@Santhosh 如果使用 loc,它会根据标签进行选择,因此在示例数据中为 -1 或 21。如果使用 iloc,则有些标签不重要,只有位置很重要。因此,在示例数据中,0 表示 iloc 的第一行,行索引为 21。类似地,-1 表示最后一行,标签应该是 1000、21、-1、20010-01-01 和一些字符串。任何值都可以,因为对于 iloc 来说并不重要。 - jezrael
1
谢谢。现在你给我解释清楚了,所以基本上 loc 只是查找一个字面字符串(与位置无关),而 iloc 则是按位置查找。同样的答案可以在此处找到:pandas.DataFrame.loc。单个标签,例如 5 或 'a',(请注意,5 被解释为索引的标签,而从不作为沿索引的整数位置)。 - Santhosh
显示剩余6条评论

1
你也可以使用 df.tail 来选择数据框的最后一行,然后将 name 列的值替换为 something:
df_query.tail(1)['name'] = 'something'

例子:

In [629]: df = pd.read_clipboard()

In [630]: df
Out[630]: 
     id  name
21  965  kris

In [631]: df.tail(1)['name'] = 'something'

In [632]: df
Out[632]: 
     id       name
21  965  something

我没有收到警告。 - Mayank Porwal
еҘҪзҡ„пјҢжҲ‘еҸӘдҪҝз”Ёdf.tail(1)['name'] = 'something'е’Ңprint(df)гҖӮ жүҖд»ҘеңЁdf.tail(1)['name'] = 'something'д№ӢеҗҺжІЎжңүдҝ®ж”№гҖӮжңүи¶ЈгҖӮ - jezrael
@jezrael 我已经添加了示例,请检查。我没有收到任何警告,输出结果也符合预期。 - Mayank Porwal
1
现已测试并且正常工作,没有出现这个错误。 - jezrael

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接