如何规范化Pandas数据框中列的列表文本?
基本上,我有一个关于Ike三明治的数据表,这个表有三列:配料 / 名称 / 价格,而配料这一列是一个配料列表,比如['x',' y',' z']。
不幸的是,当我抓取这个列表时,里面保留了一些奇怪的空格和其他格式问题,现在我想修改配料列,去掉空格并把字母都变成小写。
举个例子:
0 [Avocado, French Dressing, Gouda, Ham, Sal... Al Bundy $9.99
1 [Caesar, Halal Chicken, Marinated Artichoke ... Backstabber $9.99
2 [Bacon, Swiss, Turkey] Barry B. $8.98
3 [Avocado, Havarti, Turkey] Barry Z. $8.98
4 [Avocado, Halal Chicken, Honey Mustard, Pep... Bella $9.99
问题是:
> [x for x in mdf.ingredients[3:4]]
[[u'Avocado', u' Havarti', u' Turkey']]
注意到那些空格了吗?
我尝试过这样做:
for sandwich in mdf.ingredients:
for ingredient in sandwich:
ingredient = ingredient.strip()
ingredient = ingredient.lower()
如果我在循环中打印配料,这样可以达到我的目标,但实际上并没有改变数据表中的值。
有没有办法直接修改这些列表里的值,还是说我需要新建一列来放这些修正过的值呢?
1 个回答
1
要修改 df['ingredients']
,你可以把它赋值为一个列表的列表。比如,如果 df
看起来像这样:
import pandas as pd
df = pd.DataFrame([([u'Avocado', u' Havarti', u' Turkey'], 'Barry Z', 8.98),
([u'Bacon', u' Swiss', u'Turkey'], 'Barry B', 8.98)],
columns=['ingredients', 'name', 'price'])
print(df)
# ingredients name price
# 0 [Avocado, Havarti, Turkey] Barry Z 8.98
# 1 [Bacon, Swiss, Turkey] Barry B 8.98
那么
df['ingredients'] = [[item.strip().lower() for item in lst] for lst in df['ingredients']]
会让 df
看起来像这样
ingredients name price
0 [avocado, havarti, turkey] Barry Z 8.98
1 [bacon, swiss, turkey] Barry B 8.98
不过,拥有一个包含列表的列通常不是很方便。如果你想找出所有含有瑞士奶酪的项目,你就得逐行检查,看看每一行是否有瑞士奶酪,然后返回那一行。
如果你把数据框(DataFrame)规范化,让每个项目都有自己的列,那么这种搜索就会简单很多。
例如:
import pandas as pd
df = pd.DataFrame([([u'Avocado', u' Havarti', u' Turkey'], 'Barry Z', 8.98),
([u'Bacon', u' Swiss', u'Turkey'], 'Barry B', 8.98)],
columns=['ingredients', 'name', 'price'])
ingredients = df['ingredients'].apply(
lambda lst: pd.Series(True, index=[item.strip().lower() for item in lst]))
ingredients.fillna(False, inplace=True)
del df['ingredients']
df = df.join(ingredients)
print(df)
会生成一个看起来像这样的数据框
name price avocado bacon havarti swiss turkey
0 Barry Z 8.98 True False True False True
1 Barry B 8.98 False True False True True
现在,要找出所有包含瑞士奶酪的项目,你可以使用:
In [43]: df[df['swiss']]
Out[43]:
name price avocado bacon havarti swiss turkey
1 Barry B 8.98 False True False True True
顺便说一下,这段代码:
for ingredient in sandwich:
ingredient = ingredient.strip()
不会影响 sandwich
,因为在循环内部,变量 ingredient
被重新赋值为一个新值。这并不会改变 sandwich
中的值。理解这一点是理解 Python 的命名/引用模型 的基本要素。