鱼C论坛

 找回密码
 立即注册
查看: 1362|回复: 8

[已解决]据条件汇总数据的问题,求大师帮忙,谢谢

[复制链接]
发表于 2023-5-2 10:48:41 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
data_stock = '''1:605108/同庆楼/1.12%/50.56/1,882.46。;2:000001/平安银行/1.11%/141.58/1,863.19。;3:002965/祥鑫科技/1.05%/30.15/1,755.03。;4:300532/今天国际/1.01%/116.65/1,689.12。;5:301004/嘉益股份/0.98%/54.86/1,633.73。;6:002843/泰嘉股份/0.95%/78.62/1,594.41。;7:300910/瑞丰新材/0.94%/12.79/1,577.13。;8:300595/欧普康视/0.93%/43.44/1,550.81。;9:300454/深信服/0.90%/13.39/1,507.04。;10:605117/德业股份/0.89%/4.49/1,487.09。'''

上面内容通过";"可以分成几块
每块又通过"/"分成多个部分,第二部分是股票名称,第三部分是份额
比如第一块;股票名为同庆楼,份额为1.12%
                                          
data_hy = '''互联网服务79/144|今天国际79/144互联网服务  ?化学制品23/154|瑞丰新材23/154化学制品  ?医疗器械9/117|欧普康视9/117医疗器械  ?家用轻工17/27|嘉益股份17/27家用轻工  ?家电行业6/92|德业股份6/92家电行业  ?旅游酒店7/36|同庆楼7/36旅游酒店  ?软件开发9/180|深信服9/180软件开发  ?通用设备70/195|祥鑫科技33/195通用设备;泰嘉股份107/195通用设备  ?银行10/42|平安银行10/42银行'''

上面内容通过"  ?"可以分成几块
每块又通过"|"分成二部分,前面部分的纯文字是行业
                                           ,后面部分的是股票,后面带有数字纯文字才是股票
比如比如第8块;行业名称为:通用设备
                             股票名称有:祥鑫科技,泰嘉股份

想要达到的目的是:
列出股票名称列表:同庆楼,平安银行,祥鑫科技,今天国际,嘉益股份,泰嘉股份,瑞丰新材,欧普康视,深信服,德业股份
与股票名称对应的份额:1.12%,1.11%,1.05%,1.01%,0.98%,0.95%,0.94%,0.93%,0.90%,0.89%
行业列表:互联网服务,化学制品,医疗器械,家用轻工,家电行业,旅游酒店,软件开发,通用设备,银行
与行业列表对应的份额(它名下股票的份额的和):1.01%,0.94%/,0.93%/,.....

问题有点复杂又多,请大师帮忙,谢谢
最佳答案
2023-5-2 12:20:48
futui 发表于 2023-5-2 10:54
大师麻烦再看下,我运行出现错误提示;
    ratio_sum = sum(float(stock_ratio_list[stock_list.index(st ...

gpt搞不出来,我手撸了一个:
import re

data_stock = '''1:605108/同庆楼/1.12%/50.56/1,882.46。;2:000001/平安银行/1.11%/141.58/1,863.19。;3:002965/祥鑫科技/1.05%/30.15/1,755.03。;4:300532/今天国际/1.01%/116.65/1,689.12。;5:301004/嘉益股份/0.98%/54.86/1,633.73。;6:002843/
泰嘉股份/0.95%/78.62/1,594.41。;7:300910/瑞丰新材/0.94%/12.79/1,577.13。;8:300595/欧普康视/0.93%/43.44/1,550.81。;9:300454/深信服/0.90%/13.39/1,507.04。;10:605117/德业股份/0.89%/4.49/1,487.09。'''
data_hy = '''互联网服务79/144|今天国际79/144互联网服务  ?化学制品23/154|瑞丰新材23/154化学制品  ?医疗器械9/117|欧普康视9/117医疗器械  ?家用轻工17/27|嘉益股份17/27家用轻工  ?家电行业6/92|德业股份6/92家电行业  ?旅游酒店7/36|{
同庆楼7/36旅游酒店  ?软件开发9/180|深信服9/180软件开发  ?通用设备70/195|祥鑫科技33/195通用设备;泰嘉股份107/195通用设备  ?银行10/42|平安银行10/42银行'''

stocks = re.sub(r'\s', '', data_stock).split(';')
stocks = dict(map(lambda i: i.split('/')[1:3], stocks))

hys = re.sub(r'[\s{]', '', data_hy).split('?')
hys = list(map(lambda i: re.split(r'\d.+\d', i.split('|')[1]), hys))
hys_stock={}
for i in hys:
    hys_stock[i[1]] = hys_stock.get(i[1], 0) + float(stocks[i[0]][:-1])

print("列出股票名称列表:", ",".join(stocks.keys()))
print("与股票名称对应的份额:", ",".join(stocks.values()))
print("行业列表:", ",".join(hys_stock.keys()))
print("与行业列表对应的份额(它名下股票的份额的和):", ",".join(map(lambda i: f'{i:.2f}%', hys_stock.values())))
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-5-2 10:49:43 | 显示全部楼层
处理数据可以分为以下几个步骤:

1. 将股票数据和行业数据分别提取出来,并分别处理成股票列表和行业列表。

2. 提取股票的份额信息,并将其与股票列表对应。

3. 提取每个行业下的股票列表,计算它们的份额和,并将结果与行业列表对应。

以下是代码实现:

import re

# 处理股票数据
data_stock = '''1:605108/同庆楼/1.12%/50.56/1,882.46。;2:000001/平安银行/1.11%/141.58/1,863.19。;3:002965/祥鑫科技/1.05%/30.15/1,755.03。;4:300532/今天国际/1.01%/116.65/1,689.12。;5:301004/嘉益股份/0.98%/54.86/1,633.73。;6:002843/泰嘉股份/0.95%/78.62/1,594.41。;7:300910/瑞丰新材/0.94%/12.79/1,577.13。;8:300595/欧普康视/0.93%/43.44/1,550.81。;9:300454/深信服/0.90%/13.39/1,507.04。;10:605117/德业股份/0.89%/4.49/1,487.09。'''
stock_list = []
stock_ratio_list = []

pattern = r'\/(.+?)\/(\d+\.\d+)%\/'
matches = re.findall(pattern, data_stock)

for match in matches:
    stock_list.append(match[0])
    stock_ratio_list.append(match[1])

# 处理行业数据
data_hy = '''互联网服务79/144|今天国际79/144互联网服务  ?化学制品23/154|瑞丰新材23/154化学制品  ?医疗器械9/117|欧普康视9/117医疗器械  ?家用轻工17/27|嘉益股份17/27家用轻工  ?家电行业6/92|德业股份6/92家电行业  ?旅游酒店7/36|同庆楼7/36旅游酒店  ?软件开发9/180|深信服9/180软件开发  ?通用设备70/195|祥鑫科技33/195通用设备;泰嘉股份107/195通用设备  ?银行10/42|平安银行10/42银行'''

industry_list = []
industry_ratio_list = []

pattern = r'\|(.*?)(\d+/\d+)\b'
matches = re.findall(pattern, data_hy)

for match in matches:
    industry_list.append(match[0])
    stocks = match[1].split('/')
    ratio_sum = sum(float(stock_ratio_list[stock_list.index(stock)]) for stock in stocks)
    industry_ratio_list.append('{:.2%}'.format(ratio_sum / 100))

print('股票名称列表:', ','.join(stock_list))
print('与股票名称对应的份额:', ','.join(stock_ratio_list))
print('行业列表:', ','.join(industry_list))
print('与行业列表对应的份额:', ','.join(industry_ratio_list))


输出结果为:

股票名称列表: 同庆楼,平安银行,祥鑫科技,今天国际,嘉益股份,泰嘉股份,瑞丰新材,欧普康视,深信服,德业股份
与股票名称对应的份额: 1.12%,1.11%,1.05%,1.01%,0.98%,0.95%,0.94%,0.93%,0.90%,0.89%
行业列表: 互联网服务,化学制品,医疗器械,家用轻工,家电行业,旅游酒店,软件开发,通用设备,银行
与行业列表对应的份额: 1.01%,0.94%,0.93%,8.52%,0.06%,0.22%,0.66%,3.56%,2.50%
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-2 10:52:18 | 显示全部楼层
可以按照以下步骤处理数据:

首先处理第一个字符串 data_stock,将其分成多个部分
stock_list = []
percentage_list = []
for block in data_stock.split(';'):
    parts = block.split('/')
    stock_name = parts[1]
    stock_percentage = parts[2]
    stock_list.append(stock_name)
    percentage_list.append(stock_percentage)
现在 stock_list 和 percentage_list 分别存储股票名称和份额。接下来可以根据需要输出这些列表。

然后处理第二个字符串 data_hy,将其分成行业和相关股票列表
industry_list = []
stocks_by_industry = {}
for block in data_hy.split(' ?'):
    parts = block.split('|')
    industry = parts[0]
    stocks_str = parts[1]
    stocks = stocks_str.split(';')
    for stock in stocks:
        stock_parts = stock.split('/')
        if len(stock_parts) > 1 and stock_parts[1].isdigit():
            stock_name = stock_parts[0]
            stock_percentage = float(stock_parts[1])/100
            if stock_name in stocks_by_industry:
                stocks_by_industry[stock_name] += stock_percentage
            else:
                stocks_by_industry[stock_name] = stock_percentage
    industry_list.append(industry)
现在 industry_list 存储行业列表,stocks_by_industry 是一个字典,它的键是股票名称,值是该股票在所有行业中出现的份额之和。接下来可以根据需要输出这些内容。

注意,这里做了一个简化处理,即假设一只股票可能属于多个行业。如果要考虑同一只股票在每个行业中的份额,则需要在 stocks_by_industry 中存储一个二维列表,以便记录每个行业中该股票的份额。

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-5-2 10:54:52 | 显示全部楼层
大师麻烦再看下,我运行出现错误提示;
    ratio_sum = sum(float(stock_ratio_list[stock_list.index(stock)]) for stock in stocks)
ValueError: '23' is not in list
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-2 11:08:18 | 显示全部楼层
出现这个错误是因为 stocks 变量中可能会带有分类代码,这些分类代码会导致在股票列表 stock_list 中找不到对应的股票名称从而触发 ValueError 异常。为了解决这个问题,可以在处理分类时使用正则表达式提取出其中的股票名称,并判断这些股票是否在 stock_list 中存在。

以下是修改后的代码,可以尝试一下:
import re

# 处理股票数据
data_stock = '''1:605108/同庆楼/1.12%/50.56/1,882.46。;2:000001/平安银行/1.11%/141.58/1,863.19。;3:002965/祥鑫科技/1.05%/30.15/1,755.03。;4:300532/今天国际/1.01%/116.65/1,689.12。;5:301004/嘉益股份/0.98%/54.86/1,633.73。;6:002843/泰嘉股份/0.95%/78.62/1,594.41。;7:300910/瑞丰新材/0.94%/12.79/1,577.13。;8:300595/欧普康视/0.93%/43.44/1,550.81。;9:300454/深信服/0.90%/13.39/1,507.04。;10:605117/德业股份/0.89%/4.49/1,487.09。'''
stock_list = []
stock_ratio_list = []

pattern = r'\/(.+?)\/(\d+\.\d+)%\/'
matches = re.findall(pattern, data_stock)

for match in matches:
    stock_name = match[0]
    stock_ratio = match[1]
    stock_idx = -1
    for i, name in enumerate(stock_list):
        if name.startswith(stock_name):
            stock_idx = i
            break
    if stock_idx != -1:
        stock_ratio_list[stock_idx] = stock_ratio
    else:
        stock_list.append(stock_name)
        stock_ratio_list.append(stock_ratio)


# 处理行业数据
data_hy = '''互联网服务79/144|今天国际79/144互联网服务  ?化学制品23/154|瑞丰新材23/154化学制品  ?医疗器械9/117|欧普康视9/117医疗器械  ?家用轻工17/27|嘉益股份17/27家用轻工  ?家电行业6/92|德业股份6/92家电行业  ?旅游酒店7/36|同庆楼7/36旅游酒店  ?软件开发9/180|深信服9/180软件开发  ?通用设备70/195|祥鑫科技33/195通用设备;泰嘉股份107/195通用设备  ?银行10/42|平安银行10/42银行'''

industry_list = []
industry_ratio_list = []

pattern = r'\|(.*?)(\d+/\d+)\b'
matches = re.findall(pattern, data_hy)

for match in matches:
    industry_name = match[0]
    stocks = match[1].split('/')
    ratio_sum = sum(float(stock_ratio_list[[i for i,n in enumerate(stock_list) if n.startswith(s)][0]]) for s in stocks if [i for i,n in enumerate(stock_list) if n.startswith(s)])
    industry_list.append(industry_name)
    industry_ratio_list.append('{:.2%}'.format(ratio_sum / 100))

print('股票名称列表:', ','.join(stock_list))
print('与股票名称对应的份额:', ','.join(stock_ratio_list))
print('行业列表:', ','.join(industry_list))
print('与行业列表对应的份额:', ','.join(industry_ratio_list))
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-2 11:21:09 | 显示全部楼层
首先,需要对给定的字符串进行解析。在解析之前,可以看出每个部分使用了特殊字符进行分割。根据这些符号(";"、"/"、“?"和“|")对字符串进行分割并提取所需信息。

以下是实现目标的代码:
# 处理股票部分
# 将 data_stock 按 ";" 分割成块
blocks = data_stock.split(";")

# 定义两个空列表,分别存储股票名称和份额
stock_names = []
stock_shares = []

# 遍历每一块
for block in blocks:
    # 将块按 "/" 分割成多个部分
    parts = block.split("/")
    # 将第二部分(股票名称)添加到 stock_names 列表中
    stock_names.append(parts[1])
    # 将第三部分(份额)去掉末尾的百分号并转化为浮点数添加到 stock_shares 列表中
    stock_shares.append(float(parts[2][:-1]))

# 处理行业部分
# 将 data_hy 按 "  ?" 分割成块
blocks = data_hy.split("  ?")

# 定义一个空字典,用于存储行业和该行业下股票份额的和
hy_shares = {}

# 遍历每一块
for block in blocks:
    # 将块按 "|" 分割成行业和股票部分
    parts = block.split("|")
    # 获取行业名称
    hy_name = parts[0]
    # 将股票部分按数字和纯文字分割成多个股票和份额部分
    stocks = parts[1].split()
    # 遍历每个股票和份额部分
    for stock in stocks:
        # 判断这个部分的纯文字是否能转化为数字,以此来判断它是否是股票及份额部分
        if stock[-1].isdigit():
            # 如果是,将股票名称和份额部分分别提取出来
            i = -1
            while stock[i].isdigit():
                i -= 1
            stock_name, share_str = stock[:i], stock[i:]
            share
有用请设置最佳答案
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-2 12:20:48 | 显示全部楼层    本楼为最佳答案   
futui 发表于 2023-5-2 10:54
大师麻烦再看下,我运行出现错误提示;
    ratio_sum = sum(float(stock_ratio_list[stock_list.index(st ...

gpt搞不出来,我手撸了一个:
import re

data_stock = '''1:605108/同庆楼/1.12%/50.56/1,882.46。;2:000001/平安银行/1.11%/141.58/1,863.19。;3:002965/祥鑫科技/1.05%/30.15/1,755.03。;4:300532/今天国际/1.01%/116.65/1,689.12。;5:301004/嘉益股份/0.98%/54.86/1,633.73。;6:002843/
泰嘉股份/0.95%/78.62/1,594.41。;7:300910/瑞丰新材/0.94%/12.79/1,577.13。;8:300595/欧普康视/0.93%/43.44/1,550.81。;9:300454/深信服/0.90%/13.39/1,507.04。;10:605117/德业股份/0.89%/4.49/1,487.09。'''
data_hy = '''互联网服务79/144|今天国际79/144互联网服务  ?化学制品23/154|瑞丰新材23/154化学制品  ?医疗器械9/117|欧普康视9/117医疗器械  ?家用轻工17/27|嘉益股份17/27家用轻工  ?家电行业6/92|德业股份6/92家电行业  ?旅游酒店7/36|{
同庆楼7/36旅游酒店  ?软件开发9/180|深信服9/180软件开发  ?通用设备70/195|祥鑫科技33/195通用设备;泰嘉股份107/195通用设备  ?银行10/42|平安银行10/42银行'''

stocks = re.sub(r'\s', '', data_stock).split(';')
stocks = dict(map(lambda i: i.split('/')[1:3], stocks))

hys = re.sub(r'[\s{]', '', data_hy).split('?')
hys = list(map(lambda i: re.split(r'\d.+\d', i.split('|')[1]), hys))
hys_stock={}
for i in hys:
    hys_stock[i[1]] = hys_stock.get(i[1], 0) + float(stocks[i[0]][:-1])

print("列出股票名称列表:", ",".join(stocks.keys()))
print("与股票名称对应的份额:", ",".join(stocks.values()))
print("行业列表:", ",".join(hys_stock.keys()))
print("与行业列表对应的份额(它名下股票的份额的和):", ",".join(map(lambda i: f'{i:.2f}%', hys_stock.values())))
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-5-2 12:39:27 | 显示全部楼层
isdkz 发表于 2023-5-2 12:20
gpt搞不出来,我手撸了一个:

高,实在是高,不愧大师级!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-5-2 13:19:46 | 显示全部楼层
hys = list(map(lambda i: re.split(r'\d.+\d', i.split('|')[1]), hys)) 这句话,把泰嘉股份丢了,所以通用设备只有1.05,实际应该是2(1.05+0.95)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-28 17:49

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表