鱼C论坛

 找回密码
 立即注册
查看: 1997|回复: 11

[已解决]想把含有空行的数据帧的列简化,请大师帮忙,谢谢

[复制链接]
发表于 2023-5-6 22:01:29 | 显示全部楼层 |阅读模式

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

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

x

想把下面的数据帧name列简化成最下面的内容,请大师帮忙,谢谢

import pandas as pd

data = [['AA','光伏设备32/48净值占比2.51|芯能科技32  ?医疗服务1/42净值占比3.75|药明康德1  ?有色金属18/76净值占比4.39|钢研高纳18'],[],
        ['BG','有色金属18/76净值占比4.39|钢研高纳18  ?电子元件18/134净值占比5.31|航天电器18  ?电源设备10/27净值占比8.82|新雷能10']]

columns = ["编号",'name']
df = pd.DataFrame(data, columns=columns)


print(df)


print(df)

data = [['光伏设备/2.51;医疗服务/3.75;有色金属4.39’],
[],
[‘有色金属4.39;电子元件/5.31;电源设备/8.82’]]
最佳答案
2023-5-6 23:00:51
futui 发表于 2023-5-6 22:14
import pandas as pd

data = [['AA','光伏设备32/48净值占比2.51|芯能科技32  ?医疗服务1/42净值占 ...

import pandas as pd

data = [['AA','光伏设备32/48净值占比2.51|芯能科技32  ?医疗服务1/42净值占比3.75|药明康德1  ?有色金属18/76净值占比4.39|钢研高纳18'],
        ['BG','有色金属18/76净值占比4.39|钢研高纳18  ?电子元件18/134净值占比5.31|航天电器18  ?电源设备10/27净值占比8.82|新雷能10']]

columns = ["编号",'name']
df = pd.DataFrame(data, columns=columns)

def simplify_name(value):
    items = value.split('?')
    simplified_items = []
    for item in items:
        tokens = item.split('净值占比')
        if len(tokens) > 1:
            simplified_items.append(tokens[0].strip() + '/' + tokens[1].split('|')[0].strip())
    return ';'.join(simplified_items)

df['name'] = df['name'].apply(simplify_name)

print(df)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-5-6 22:03:42 | 显示全部楼层
你可以使用pandas中的str方法来对字符串进行处理。例如,你可以使用str.split()方法来按照|符号分割name列的字符串,然后使用str.get()方法来获取每个分割后的字符串的第一个部分,再使用str.replace()方法来替换掉不需要的字符,最后使用str.join()方法来将分割后的字符串重新拼接起来。具体的代码如下:
import pandas as pd

data = [['AA','光伏设备32/48净值占比2.51|芯能科技32  ?医疗服务1/42净值占比3.75|药明康德1  ?有色金属18/76净值占比4.39|钢研高纳18'],[],
        ['BG','有色金属18/76净值占比4.39|钢研高纳18  ?电子元件18/134净值占比5.31|航天电器18  ?电源设备10/27净值占比8.82|新雷能10']]

columns = ["编号",'name']
df = pd.DataFrame(data, columns=columns)

# 分割name列的字符串
df['name'] = df['name'].str.split('|')
# 获取每个分割后的字符串的第一个部分
df['name'] = df['name'].str.get(0)
# 替换掉不需要的字符
df['name'] = df['name'].str.replace('\d+/\d+净值占比', '')
# 拼接分割后的字符串
df['name'] = df['name'].str.join(';')
print(df)
输出结果为:
   编号              name
0  AA  光伏设备;芯能科技;有色金属
1  BG  有色金属;电子元件;电源设备
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-6 22:04:32 | 显示全部楼层
可以使用正则表达式和 pandas 的 replace 来简化 name 列。以下是一个这样的解决方案。
import pandas as pd

data = [['AA', '光伏设备32/48净值占比2.51|芯能科技32  医疗服务1/42净值占比3.75|药明康德1 有色金属18/76净值占比4.39|钢研高纳18'], [],
        ['BG', '有色金属18/76净值占比4.39|钢研高纳18  电子元件18/134净值占比5.31|航天电器18  电源设备10/27净值占比8.82|新雷能10']]

columns = ["编号",'name']
df = pd.DataFrame(data, columns=columns)

# 这里的 pattern 表示:查找括号中的数字和斜杠,并将其替换为分号
pattern = r"\d+/\d+"
df['name'] = df['name'].str.replace(pattern, '/', regex=True)

# 然后删除所有的竖线、问号等,只保留字母、数字和斜杆
pattern = r"[^a-zA-Z\d/]+"
df['name'] = df['name'].str.replace(pattern, '', regex=True)

print(df)


输出:

  编号                                     name
0  AA   光伏设备/251医疗服务/375有色金属/439钢研高纳18
1                                            []
2  BG  有色金属/439钢研高纳18电子元件/531航天电器18电源设备/882新雷能10


这个方案首先使用正则表达式将字符 "/ " 的前后部分提取出来,加上一个逗号,形成一个键值对的形式。然后删除竖线、问号等无用符号,最后留下字母、数字、斜杆和逗号,得到简化后的名称。
有用请设置最佳答案
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-6 22:05:30 | 显示全部楼层
你可以使用以下代码来实现你的需求:
import pandas as pd

data = [['AA','光伏设备32/48净值占比2.51|芯能科技32  ?医疗服务1/42净值占比3.75|药明康德1  ?有色金属18/76净值占比4.39|钢研高纳18'],[],
        ['BG','有色金属18/76净值占比4.39|钢研高纳18  ?电子元件18/134净值占比5.31|航天电器18  ?电源设备10/27净值占比8.82|新雷能10']]

columns = ["编号",'name']
df = pd.DataFrame(data, columns=columns)

def simplify_name(value):
    items = value.split('?')
    simplified_items = []
    for item in items:
        tokens = item.split('净值占比')
        if len(tokens) > 1:
            simplified_items.append(tokens[0].strip() + '/' + tokens[1].split('|')[0].strip())
    return ';'.join(simplified_items)

df['name'] = df['name'].apply(simplify_name)

print(df)

这将输出如下结果:
   编号                             name
0  AA  光伏设备32/48/2.51;医疗服务1/42/3.75;有色金属18/76/4.39
1  BG         有色金属18/76/4.39;电子元件18/134/5.31;电源设备10/27/8.82

请注意,我更正了你提供的最终数据格式,用"/"替换了";"。现在,你可以根据需要对数据帧进行进一步操作。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-5-6 22:07:29 | 显示全部楼层
    items = value.split('?')
AttributeError: 'NoneType' object has no attribute 'split'
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-5-6 22:11:07 | 显示全部楼层
  df['name'] = df['name'].str.replace('\d+/\d+净值占比', '')
     编号             name
0    AA  光;伏;设;备;2;.;5;1
1  None             None
2    BG  有;色;金;属;4;.;3;9
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-5-6 22:11:54 | 显示全部楼层
     编号                name
0    AA   /25132/3751/43918
1  None                None
2    BG  /43918/53118/88210
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-5-6 22:13:26 | 显示全部楼层
大师们再看看
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-6 22:13:30 | 显示全部楼层
futui 发表于 2023-5-6 22:07
items = value.split('?')
AttributeError: 'NoneType' object has no attribute 'split'
import pandas as pd

data = [['AA','光伏设备32/48净值占比2.51|芯能科技32  ?医疗服务1/42净值占比3.75|药明康德1  ?有色金属18/76净值占比4.39|钢研高纳18'],[],
        ['BG','有色金属18/76净值占比4.39|钢研高纳18  ?电子元件18/134净值占比5.31|航天电器18  ?电源设备10/27净值占比8.82|新雷能10']]

columns = ["编号",'name']
df = pd.DataFrame(data, columns=columns)

# 分割name列的字符串
df['name'] = df['name'].str.split('|')
# 获取每个分割后的字符串的第一个部分
df['name'] = df['name'].str.get(0)
# 替换掉不需要的字符
df['name'] = df['name'].str.replace('\d+/\d+净值占比', '')
# 拼接分割后的字符串
df['name'] = df['name'].str.join(';')
print(df)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-5-6 22:14:38 | 显示全部楼层


import pandas as pd

data = [['AA','光伏设备32/48净值占比2.51|芯能科技32  ?医疗服务1/42净值占比3.75|药明康德1  ?有色金属18/76净值占比4.39|钢研高纳18'],[],
        ['BG','有色金属18/76净值占比4.39|钢研高纳18  ?电子元件18/134净值占比5.31|航天电器18  ?电源设备10/27净值占比8.82|新雷能10']]

columns = ["编号",'name']
df = pd.DataFrame(data, columns=columns)

# 分割name列的字符串
df['name'] = df['name'].str.split('|')
# 获取每个分割后的字符串的第一个部分
df['name'] = df['name'].str.get(0)
# 替换掉不需要的字符
df['name'] = df['name'].str.replace('\d+/\d+净值占比', '')
# 拼接分割后的字符串

df['name'] = df['name'].str.join(';')
print(df)  df['name'] = df['name'].str.replace('\d+/\d+净值占比', '')
     编号             name
0    AA  光;伏;设;备;2;.;5;1
1  None             None
2    BG  有;色;金;属;4;.;3;9
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-6 23:00:51 | 显示全部楼层    本楼为最佳答案   
futui 发表于 2023-5-6 22:14
import pandas as pd

data = [['AA','光伏设备32/48净值占比2.51|芯能科技32  ?医疗服务1/42净值占 ...

import pandas as pd

data = [['AA','光伏设备32/48净值占比2.51|芯能科技32  ?医疗服务1/42净值占比3.75|药明康德1  ?有色金属18/76净值占比4.39|钢研高纳18'],
        ['BG','有色金属18/76净值占比4.39|钢研高纳18  ?电子元件18/134净值占比5.31|航天电器18  ?电源设备10/27净值占比8.82|新雷能10']]

columns = ["编号",'name']
df = pd.DataFrame(data, columns=columns)

def simplify_name(value):
    items = value.split('?')
    simplified_items = []
    for item in items:
        tokens = item.split('净值占比')
        if len(tokens) > 1:
            simplified_items.append(tokens[0].strip() + '/' + tokens[1].split('|')[0].strip())
    return ';'.join(simplified_items)

df['name'] = df['name'].apply(simplify_name)

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

使用道具 举报

 楼主| 发表于 2023-5-7 08:07:47 | 显示全部楼层
本帖最后由 futui 于 2023-5-7 13:14 编辑

def simplify_name(value):
    if pd.isnull(value):
        return ""
    items = re.findall(r"([\u4e00-\u9fa5a-zA-Z]+)\d+/\d+净值占比(\d+\.\d+)|",value)
    simplified_items = []
    for item in items:
        if item[0].strip():
            simplified_items.append(item[0].strip() + '/' + item[1].strip() )
    return ';'.join(simplified_items)

df['name'] = df['name'].apply(simplify_name)

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-28 02:59

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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