![](/img/trans.png)
[英]How to efficiently fix JSON file converted from pandas dataframe
[英]How to map values (from a CSV file) with Pandas DataFrame efficiently?
我有一个像这样的 CSV:
第一列可以有间隙,但第二列和第三列在值的中间没有间隙。
列TO_REPLACE
的值应替换为列TO_REPLACE
的值, VALUE_TO_COPY
是其单元格的内容与列TO_SEARCH
的单元格值TO_SEARCH
。 所以结果应该是这样的:
我写了一个脚本:
import pandas as pd
import numpy as np
df = pd.read_csv(
filepath_or_buffer='mapping_test.csv',
delimiter=',',
dtype=str
)
to_replace = df['TO_REPLACE'].copy()
result = df['TO_REPLACE'].copy()
df = df.set_index('TO_SEARCH')
df.dropna(
how='all',
inplace=True
)
del df['TO_REPLACE']
for key, value in to_replace.iteritems():
try:
result[key] = df.loc[value, 'VALUE_TO_COPY']
except:
print('ERROR, not found KEY: {}'.format(key))
result_df = pd.DataFrame(
data={
'TO_REPLACE': result,
'VALUE_TO_COPY': list(df['VALUE_TO_COPY']) + [np.nan] * (len(result) - df['VALUE_TO_COPY'].size),
'TO_SEARCH': list(df.index) + [np.nan] * (len(result) - df['VALUE_TO_COPY'].size),
},
columns=['TO_REPLACE','VALUE_TO_COPY','TO_SEARCH'] # to preserve the column order
)
result_df.to_csv(
path_or_buf='mapping_result.csv',
index=False
)
我在我的代码中做什么:
我将 CSV 中的数据读入 DataFrame
我将 DataFrame 分成两部分。 一方面我将TO_REPLACE
存储为一个系列,另一方面存储一个 DataFrame 与列VALUE_TO_COPY
和TO_SEARCH
。 我使用TO_SEARCH
作为这个 DataFrame 的索引。
我遍历列TO_REPLACE
,以便找到在列中的值TO_SEARCH
。 如果值不一致,我保留旧值。
我使用替换的值再次构建一个 DataFrame 并将其存储到一个 CSV 文件中。
但是效率不是很高。 我需要经常映射数千个值,这就是为什么我需要更高效的代码。 任何想法来增强我的代码?
也许我可以使用map
(对于 Series)、 apply
或applymap
(对于 DF)方法。 至少我已经放弃了apply
因为它一次对整行进行操作,而applymap
对整个 DataFrame 进行操作。 也许最有用的是map
,但我认为它会像我手动那样遍历所有值。 我考虑过的另一个可能的选择是方法replace
,但我读过map
更快。
2018-09-03_map_with_pandas.ipynb
import pandas as pd
df = pd.read_csv('data/RBefh.csv', dtype=str)
keys = list(df['to_search'].dropna())
values = list(df['value_to_copy'].dropna())
map_values = dict(zip(keys, values))
mapper = df.to_replace.isin(map_values)
df.loc[mapper, 'to_replace'] = df.loc[mapper, 'to_replace'].apply(lambda row: map_values[row])
df.fillna('', inplace=True)
输出:
to_replace value_to_copy to_search
0 __import__.value_1 __import__.value_1 2012000401
1 __import__.value_1 __import__.value_2 2012000501
2 __import__.value_1 __import__.value_3 2012000601
3 __import__.value_2 __import__.value_4 2012000603
4 __import__.value_2 __import__.value_5 2012000604
5 __import__.value_2 __import__.value_6 2012000605
6 __import__.value_7 2012000606
7 __import__.value_2 __import__.value_8 2012000607
8 __import__.value_2 __import__.value_9 2012000608
9 __import__.value_2 __import__.value_10 2012000609
10 __import__.value_11 2012000610
11 __import__.value_2 __import__.value_12 2012000701
12 __import__.value_2 __import__.value_13 2012000702
13 __import__.value_3
14 __import__.value_4
15 __import__.value_5
16 __import__.value_6
17 __import__.value_7
18 __import__.value_8
19 __import__.value_9
20 __import__.value_10
21 __import__.value_11
22 __import__.value_12
23 __import__.value_12
24 __import__.value_12
25 __import__.value_12
26 __import__.value_12
27 __import__.value_12
28 __import__.value_12
29 2012999999
我不会使用熊猫。
我会将它们从生成器读入字典。
使用它来访问数据:
def read_file(fullname):
with open(fullname) as f:
for index, line in enumerate(f):
if index == 0:
header_line = line
else:
yield header_line, line
myFile = read_file(r"Path/To/Your/File")
for header, line in myFile:
data = dict(zip(header.split(" "), line.split(" ")))
.....
并创建一个crosswalk_dict
/several crosswalk dicts,在循环生成器时填充这些字典。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.