原始数据结构如下,总共 7000 多条,想扁平化然后放到 pd 里面做进一步的处理
>>> len(funds)
7597
>>> funds[0]
{'000005': {'company': '嘉实', 'name': '嘉实增强信用定期债券', 'type': '定开债券', 'earning': {'1m': 0.1, '3m': 1.0, '6m': 0.85, '1y': 2.59}, 'hold_stocks': [{'code': '601966', 'name': '玲珑轮胎', 'percentage': '0.51%', 'volume': 0.67, 'value': 23.48}, {'code': '002745', 'name': '木林森', 'percentage': '0.47%', 'volume': 1.5, 'value': 21.92}]}}
>>> funds[-1]
{'970008': {'company': '华安', 'name': '华安证券汇赢增利一年持有混合 C', 'type': '混合型', 'earning': {'1m': -0.55, '3m': -0.58, '6m': 0.67, '1y': 0}, 'hold_stocks': [{'code': '300692', 'name': '中环环保', 'percentage': '0.72%', 'volume': 31.81, 'value': 496.79}, {'code': '603012', 'name': '创力集团', 'percentage': '0.67%', 'volume': 72.28, 'value': 465.48}, {'code': '300197', 'name': '铁汉生态', 'percentage': '0.64%', 'volume': 138.93, 'value': 440.39}, {'code': '002562', 'name': '兄弟科技', 'percentage': '0.23%', 'volume': 31.0, 'value': 160.27}]}}
>>>
生成 df 代码如下:
df = pd.DataFrame(columns=['fund_code', 'fund_company', 'stock_code', 'stock_name', 'stock_percentage', 'stock_volume', 'stock_value'])
i = 0
for fund in funds:
fund_code = list(fund.keys())[0]
fund_company = list(fund.values())[0]['company']
if list(fund.values())[0]['hold_stocks']:
for hold_stock in list(fund.values())[0]['hold_stocks']:
stock_code = hold_stock['code'].strip()
stock_name = hold_stock['name'].strip()
stock_percentage = float(hold_stock['percentage'].strip('%'))
stock_volume = hold_stock['volume']
stock_value = hold_stock['value']
df.loc[i] = [fund_code, fund_company, stock_code, stock_name, stock_percentage, stock_volume, stock_value]
i += 1
else:
df.loc[i] = [fund_code, fund_company, '', '', 0, 0, 0] # 不持仓任何股票则仅记录基金代码和基金公司
i += 1
1
bigtan 2021-02-10 11:33:15 +08:00 via iPhone
pd.Dataframe.from_dict
|
2
bigtan 2021-02-10 11:35:54 +08:00 via iPhone
你不是生成了一张表,而是几万张
|
3
binux 2021-02-10 11:48:32 +08:00 via Android
一次把数据喂给 dataframe
|
4
lv2016 2021-02-10 11:57:15 +08:00
直接修改 dataframe 确实很慢,建议先生成 list,再转 dataframe
|
5
WinG 2021-02-10 12:03:41 +08:00
量化炒股???
|
8
princelai 2021-02-10 12:59:51 +08:00 1
楼上说了,每次操作 df 是很慢的,可以操作 json 变为适合的格式,然后一次性给 pandas
``` from pandas import json_normalize funds = [{'000005': {'company': '嘉实', 'name': '嘉实增强信用定期债券', 'type': '定开债券', 'earning': {'1m': 0.1, '3m': 1.0, '6m': 0.85, '1y': 2.59}, 'hold_stocks': [{'code': '601966', 'name': '玲珑轮胎', 'percentage': '0.51%', 'volume': 0.67, 'value': 23.48}, {'code': '002745', 'name': '木林森', 'percentage': '0.47%', 'volume': 1.5, 'value': 21.92}]}}, {'970008': {'company': '华安', 'name': '华安证券汇赢增利一年持有混合 C', 'type': '混合型', 'earning': {'1m': -0.55, '3m': -0.58, '6m': 0.67, '1y': 0}, 'hold_stocks': [{'code': '300692', 'name': '中环环保', 'percentage': '0.72%', 'volume': 31.81, 'value': 496.79}, {'code': '603012', 'name': '创力集团', 'percentage': '0.67%', 'volume': 72.28, 'value': 465.48}, {'code': '300197', 'name': '铁汉生态', 'percentage': '0.64%', 'volume': 138.93, 'value': 440.39}, {'code': '002562', 'name': '兄弟科技', 'percentage': '0.23%', 'volume': 31.0, 'value': 160.27}]}}] new_funds = [] for fund in funds: for k, v in fund.items(): v.update({'code': k}) new_funds.append(v) df = json_normalize(new_funds, 'hold_stocks', ['company', 'name', 'type', 'code'], meta_prefix='fund_', record_prefix='stock_') ``` |
9
princelai 2021-02-10 13:01:00 +08:00
缩进乱了,new_funds.append 是在两层循环里,json_normalize 是在最外层,循环完毕才去执行的
|
10
Escapist367 2021-02-10 13:41:45 +08:00
df_list=[]
i = 0 for fund in funds: fund_code = list(fund.keys())[0] fund_company = list(fund.values())[0]['company'] if list(fund.values())[0]['hold_stocks']: for hold_stock in list(fund.values())[0]['hold_stocks']: stock_code = hold_stock['code'].strip() stock_name = hold_stock['name'].strip() stock_percentage = float(hold_stock['percentage'].strip('%')) stock_volume = hold_stock['volume'] stock_value = hold_stock['value'] df_list.append([fund_code, fund_company, stock_code, stock_name, stock_percentage, stock_volume, stock_value]) i += 1 else: df_list.append([fund_code, fund_company, '', '', 0, 0, 0]) # 不持仓任何股票则仅记录基金代码和基金公司 i += 1 df = pd.DataFrame(df_list,columns=['fund_code', 'fund_company', 'stock_code', 'stock_name', 'stock_percentage', 'stock_volume', 'stock_value']) ================== 在你基础上最小改动。 你先用一个 list 存放每行结果,再一次性转 df 就行了,大概只要 1s |
11
yaleyu OP @princelai 缩进乱了没事,好像 V2 回复不能用 markdown 格式。
你这个太牛了,时间从 7 分多钟缩短到 0.5 秒了,不过数据从 45639 行减少成了 42138 行,我再仔细检查一下哪些数据被抛弃了。 新年快乐哈。 |
12
billgreen1 2021-02-10 13:51:39 +08:00
@princelai 这个赞,我之前都不了解这个函数
|
13
youthfire 2021-02-10 13:57:47 +08:00 via iPhone
pandas 速度还是很快的,我的经验是基本上百万级的,论分钟的话多半是嵌套写错了在低效执行。数据库处理的话优势更明显。
|
14
winglight2016 2021-02-10 15:10:52 +08:00
你用了两层 for 然后调用 loc 方法,当然会慢呀。记得减少 for 循环次数以及 loc 调用次数。
pandas 的优势在 dataframe 的批处理上,尽量把计算操作放到 dataframe/series 的原生方法里进行,大部分需求应该都能满足。 |
15
lixuda 2021-02-10 19:47:11 +08:00
pandas 不要用 for,用 apply 。
|
16
allAboutDbmss 2021-02-11 02:24:15 +08:00
https://github.com/modin-project/modin
我每天都向人推荐这个 |
17
owenliang 2021-02-11 09:10:36 +08:00
学学 pyspark 。
|
18
fxrocks 2021-02-11 10:46:42 +08:00 via Android
1 楼正解
|
19
volvo007 2021-02-12 00:05:53 +08:00 via iPhone
还有个函数
pd.json_normalize,可以把半结构化的 json (比如数组套对象又套数组而且不同组嵌套不一样的)转为字典,而且可以有选择性地抽取 json 中的某些字段 贼好用 |