在 DataFrame 中为 NaN 添加值时出现问题
Trouble when adding values for NaN in DataFrame
我有这个数据框:
manufacturer description
0 toyota toyota, gmc 10 years old.
1 NaN gmc, Motor runs and drives good.
2 NaN Motor old, in pieces.
3 NaN 2 owner 0 rust. Cadillac.
我想用描述中的关键字填充 NaN 值。为此,我创建了一个包含我想要的关键字的列表:
keyword = ['gmc', 'toyota', 'cadillac']
最后,我想遍历 DataFrame 中的每一行。拆分每行“描述”列中的内容,如果该词也在“关键字”列表中,则将其添加到“制造商”列中。例如,它看起来像这样:
manufacturer description
0 toyota toyota, gmc 10 years old.
1 gmc gmc, Motor runs and drives good.
2 NaN Motor old, in pieces.
3 cadillac 2 owner 0 rust. Cadillac.
感谢这个社区中的某个人,我可以改进我的代码:
import re
keyword = ['gmc', 'toyota', 'cadillac']
bag_of_words = []
for i, description in enumerate(test3['description']):
bag_of_words = re.findall(r"""[A-Za-z\-]+""", test3["description"][i])
for word in bag_of_words:
if word.lower() in keyword:
test3.loc[i, 'manufacturer'] = word.lower()
但我意识到第一行也改变了值,即使它不是 NaN:
manufacturer description
0 gmc toyota, gmc 10 years old.
1 gmc gmc, Motor runs and drives good.
2 NaN Motor old, in pieces.
3 cadillac 2 owner 0 rust. Cadillac.
我只想更改 NaN 值,但是当我尝试添加时:
if word.lower() in keyword and test3.loc[i, 'manufacturer'] == np.nan:
没有任何效果。
np.nan == np.nan
为假。也许有点违反直觉 =) 但这应该意味着最后一个条件永远不应该启动。从你的问题中不清楚你是否看到相同的结果或没有结果。
如果你改变了
for i, description in enumerate(test3['description']):
至
for i, description in zip(test3.loc[test3['manufacturer'].isna(), :].index, test3.loc[test3['manufacturer'].isna(), 'description']):
那么我认为它应该可以正常工作。您只会得到 'manufacturer' 为 NaN 的行。您还可以删除 == np.nan
部分,因为非空字符串的计算结果为 True 而 np.nan 的计算结果为 False 但这会使您的代码更难理解。
有很多方法可以让您的代码看起来更漂亮 ;) 但要专注于学习调试,其余的就会来。只要它做你想让它做的事,谁在乎呢。
您可以调试的一种方法是在循环内打印条件的每个部分的真值。
print(bool(word.lower() in keyword))
print(bool(test3.loc[i, 'manufacturer'] == np.nan)
祝福!
编辑:好的,我应该添加我自己的做法。
df = pd.DataFrame({'manufacturer': ['toyota', np.nan, np.nan, np.nan],
'description': ['toyota, gmc 10 years old.', 'gmc, Motor runs and drives good.', 'Motor old, in pieces.', '2 owner 0 rust. Cadillac.']})
keyword = ['gmc', 'toyota', 'cadillac']
filler = df['description'].map(lambda s: [word for word in keyword if word in s.lower()][0]
if bool([word for word in keyword if word in s.lower()])
else np.nan)
df['manufacturer'] = df['manufacturer'].fillna(filler)
当两者都出现在字符串中时,不确定您是否需要关键字中的最后一项或第一项。我在这里使用索引 0 将它设置为第一项。
我有这个数据框:
manufacturer description
0 toyota toyota, gmc 10 years old.
1 NaN gmc, Motor runs and drives good.
2 NaN Motor old, in pieces.
3 NaN 2 owner 0 rust. Cadillac.
我想用描述中的关键字填充 NaN 值。为此,我创建了一个包含我想要的关键字的列表:
keyword = ['gmc', 'toyota', 'cadillac']
最后,我想遍历 DataFrame 中的每一行。拆分每行“描述”列中的内容,如果该词也在“关键字”列表中,则将其添加到“制造商”列中。例如,它看起来像这样:
manufacturer description
0 toyota toyota, gmc 10 years old.
1 gmc gmc, Motor runs and drives good.
2 NaN Motor old, in pieces.
3 cadillac 2 owner 0 rust. Cadillac.
感谢这个社区中的某个人,我可以改进我的代码:
import re
keyword = ['gmc', 'toyota', 'cadillac']
bag_of_words = []
for i, description in enumerate(test3['description']):
bag_of_words = re.findall(r"""[A-Za-z\-]+""", test3["description"][i])
for word in bag_of_words:
if word.lower() in keyword:
test3.loc[i, 'manufacturer'] = word.lower()
但我意识到第一行也改变了值,即使它不是 NaN:
manufacturer description
0 gmc toyota, gmc 10 years old.
1 gmc gmc, Motor runs and drives good.
2 NaN Motor old, in pieces.
3 cadillac 2 owner 0 rust. Cadillac.
我只想更改 NaN 值,但是当我尝试添加时:
if word.lower() in keyword and test3.loc[i, 'manufacturer'] == np.nan:
没有任何效果。
np.nan == np.nan
为假。也许有点违反直觉 =) 但这应该意味着最后一个条件永远不应该启动。从你的问题中不清楚你是否看到相同的结果或没有结果。
如果你改变了
for i, description in enumerate(test3['description']):
至
for i, description in zip(test3.loc[test3['manufacturer'].isna(), :].index, test3.loc[test3['manufacturer'].isna(), 'description']):
那么我认为它应该可以正常工作。您只会得到 'manufacturer' 为 NaN 的行。您还可以删除 == np.nan
部分,因为非空字符串的计算结果为 True 而 np.nan 的计算结果为 False 但这会使您的代码更难理解。
有很多方法可以让您的代码看起来更漂亮 ;) 但要专注于学习调试,其余的就会来。只要它做你想让它做的事,谁在乎呢。
您可以调试的一种方法是在循环内打印条件的每个部分的真值。
print(bool(word.lower() in keyword))
print(bool(test3.loc[i, 'manufacturer'] == np.nan)
祝福!
编辑:好的,我应该添加我自己的做法。
df = pd.DataFrame({'manufacturer': ['toyota', np.nan, np.nan, np.nan],
'description': ['toyota, gmc 10 years old.', 'gmc, Motor runs and drives good.', 'Motor old, in pieces.', '2 owner 0 rust. Cadillac.']})
keyword = ['gmc', 'toyota', 'cadillac']
filler = df['description'].map(lambda s: [word for word in keyword if word in s.lower()][0]
if bool([word for word in keyword if word in s.lower()])
else np.nan)
df['manufacturer'] = df['manufacturer'].fillna(filler)
当两者都出现在字符串中时,不确定您是否需要关键字中的最后一项或第一项。我在这里使用索引 0 将它设置为第一项。