#python #pandas #dictionary
#python #pandas #словарь
Вопрос:
У меня есть фрейм данных с примерно 200 000 точками данных и столбцом, который выглядит следующим образом (пример для 1 точки данных):
'{"id":342,"name":"Web","slug":"technology/web","position":15,"parent_id":16,"color":6526716,"urls":{"web":{"discover":"http://www.kickstarter.com/discover/categories/technology/web"}}}'
Я хочу извлечь информацию об имени и пуле. Я сделал следующее:
df["cat"], df["slug"] = np.nan, np.nan
for i in range(0, len(df.category)):
df["cat"][i] = df.category.iloc[i].split('"name":"')[1].split('"')[0]
df["slug"][i] = df.category.iloc[i].split('"name":"')[1].split('"')[4]
Это работает отлично, но занимает около 4 часов. Есть ли какой-либо способ ускорить это?
Комментарии:
1. Как создается фрейм данных?
Ответ №1:
Вместо того, чтобы напрямую манипулировать фреймом данных, попробуйте использовать простые типы данных и создайте фрейм данных за один раз. Другое решение, отличное от jezrael’s:
import json
cat, slug = [], []
for row in df.category:
d = json.loads(row)
cat.append(d['cat'])
slug.append(d['slug'])
df = pd.DataFrame({'cat': cat, 'slug': slug})
Ответ №2:
Вы можете сделать это очень эффективно с extract
и регулярными выражениями:
df['cat'] = df['category'].str.extract('"name":"([^"] )"')
df['slug'] = df['category'].str.extract('"slug":"([^"] )"')
df
Вопрос был об улучшении скорости, поэтому вот сравнение производительности (протестировано на примере 100 000 строк; см. Примечание ниже):
%%timeit
df['cat'] = df['category'].str.extract('"name":"([^"] )"')
df['slug'] = df['category'].str.extract('"slug":"([^"] )"')
309 ms ± 10.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%%timeit
cat, slug = [], []
for row in df.category:
d = json.loads(row)
cat.append(d['name'])
slug.append(d['slug'])
df1 = pd.DataFrame({'cat': cat, 'slug': slug})
574 ms ± 6.57 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%%timeit
df1 = pd.DataFrame([ast.literal_eval(x) for x in df['category']],
index=df.index)[['name','slug']]
5.1 s ± 29 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Примечание: пример, созданный с:
x = '{"id":342,"name":"Web","slug":"technology/web","position":15,"parent_id":16,"color":6526716,"urls":{"web":{"discover":"http://www.kickstarter.com/discover/categories/technology/web"}}}'
df = pd.DataFrame({'category': [x]*100000})