loc 和 iloc 方法在分配时的行为是否不同?
Do loc and iloc methods behave differently in assignment?
我需要根据另一个数据框中的 ID 将新列添加到数据框中。
我创建了一小段我正在尝试做的事情:
import pandas as pd
import numpy as np
a = pd.DataFrame([['ass-123-43', ['123', '456']],['ass-123-44', ['123', '457']]], columns=['customer_id', 'order_id'])
b = pd.DataFrame([['ass-123-43'], ['ass-123-44']], columns=['customer_id'])
dict_a = a.set_index('customer_id').order_id.to_dict()
b['order_id'] = np.nan
for customer_id, order_id in dict_a.items():
if customer_id in b.customer_id.values:
b.iloc[b.customer_id == customer_id, 1] = pd.Series([order_id])
print(b)
当我使用 iloc 方法时,代码按预期工作:
customer_id order_id
0 ass-123-43 [123, 456]
1 ass-123-44 [123, 457]
但是当我使用 loc 方法时它没有按预期工作:
import pandas as pd
import numpy as np
a = pd.DataFrame([['ass-123-43', ['123', '456']],['ass-123-44', ['123', '457']]], columns=['customer_id', 'order_id'])
b = pd.DataFrame([['ass-123-43'], ['ass-123-44']], columns=['customer_id'])
dict_a = a.set_index('customer_id').order_id.to_dict()
b['order_id'] = np.nan
for customer_id, order_id in dict_a.items():
if customer_id in b.customer_id.values:
b.loc[b.customer_id == customer_id, 'order_id'] = pd.Series([order_id])
print(b)
我得到了这个结果:
customer_id order_id
0 ass-123-43 [123, 456]
1 ass-123-44 NaN
除了 loc 使用标签分配行和 iloc 一个数字之外,还有什么我错过的吗?
您可以详细了解 .iloc
和 .loc
之间的差异,但对于您的特定情况,您得到 NaN 的原因是 你要分配什么。使用 .iloc
,它完全忽略了您分配的值的 index(即 pd.Series([order_id])
),因此它工作正常并且不会产生 NaN .
然而,对于 .loc
,它 尊重索引。在您的示例中,pd.Series([order_id])
的索引为 [0]
,如您所见:
>>> order_id = '123'
>>> pd.Series([order_id])
0 123
dtype: object
现在查看出现 NaN 的行的索引。是 1
。但是您尝试分配给它的值的索引是 0
,如上所示。 索引不匹配! 发生了什么?缺失值 - NaN.
如果您想要使用.loc
而不是.iloc
,您可以通过将 Series 对象转换为 numpy 来避免这个 mismatched-index 问题分配前的数组(使用 .to_numpy()
):
b.loc[b.customer_id == customer_id, 'order_id'] = pd.Series([order_id]).to_numpy()
这将按预期工作。
我需要根据另一个数据框中的 ID 将新列添加到数据框中。
我创建了一小段我正在尝试做的事情:
import pandas as pd
import numpy as np
a = pd.DataFrame([['ass-123-43', ['123', '456']],['ass-123-44', ['123', '457']]], columns=['customer_id', 'order_id'])
b = pd.DataFrame([['ass-123-43'], ['ass-123-44']], columns=['customer_id'])
dict_a = a.set_index('customer_id').order_id.to_dict()
b['order_id'] = np.nan
for customer_id, order_id in dict_a.items():
if customer_id in b.customer_id.values:
b.iloc[b.customer_id == customer_id, 1] = pd.Series([order_id])
print(b)
当我使用 iloc 方法时,代码按预期工作:
customer_id order_id
0 ass-123-43 [123, 456]
1 ass-123-44 [123, 457]
但是当我使用 loc 方法时它没有按预期工作:
import pandas as pd
import numpy as np
a = pd.DataFrame([['ass-123-43', ['123', '456']],['ass-123-44', ['123', '457']]], columns=['customer_id', 'order_id'])
b = pd.DataFrame([['ass-123-43'], ['ass-123-44']], columns=['customer_id'])
dict_a = a.set_index('customer_id').order_id.to_dict()
b['order_id'] = np.nan
for customer_id, order_id in dict_a.items():
if customer_id in b.customer_id.values:
b.loc[b.customer_id == customer_id, 'order_id'] = pd.Series([order_id])
print(b)
我得到了这个结果:
customer_id order_id
0 ass-123-43 [123, 456]
1 ass-123-44 NaN
除了 loc 使用标签分配行和 iloc 一个数字之外,还有什么我错过的吗?
您可以详细了解 .iloc
和 .loc
.iloc
,它完全忽略了您分配的值的 index(即 pd.Series([order_id])
),因此它工作正常并且不会产生 NaN .
然而,对于 .loc
,它 尊重索引。在您的示例中,pd.Series([order_id])
的索引为 [0]
,如您所见:
>>> order_id = '123'
>>> pd.Series([order_id])
0 123
dtype: object
现在查看出现 NaN 的行的索引。是 1
。但是您尝试分配给它的值的索引是 0
,如上所示。 索引不匹配! 发生了什么?缺失值 - NaN.
如果您想要使用.loc
而不是.iloc
,您可以通过将 Series 对象转换为 numpy 来避免这个 mismatched-index 问题分配前的数组(使用 .to_numpy()
):
b.loc[b.customer_id == customer_id, 'order_id'] = pd.Series([order_id]).to_numpy()
这将按预期工作。