原始数据结构如下,总共 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 ![]() 楼上说了,每次操作 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 中的某些字段 贼好用 |