You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将CSV导入Pandas并按列值生成层级JSON结构的技术问询

用C# CSVHelper + AutoMapper实现CSV分组转层级JSON

步骤1:定义实体类

先对应CSV行和最终输出结构定义强类型类,方便后续处理:

// 对应CSV每行数据的实体
public class CsvLocationRecord
{
    public int personal_id { get; set; }
    public string location_type { get; set; }
    public int location_number { get; set; }
}

// 最终输出的层级结构实体
public class PersonalLocationResult
{
    public int personal_id { get; set; }
    public List<int>? company { get; set; }
    public List<int>? branch { get; set; }
}

步骤2:用CSVHelper流式读取CSV

针对数十万行的大文件,必须用流式读取避免内存溢出,同时处理CSV中location_type带单引号的格式:

using var reader = new StreamReader("你的CSV文件路径.csv");
using var csv = new CsvReader(reader, CultureInfo.InvariantCulture);

// 配置读取规则:忽略大小写匹配表头,解析带单引号的字符串
csv.Configuration.PrepareHeaderForMatch = header => header.ToLower();
csv.Configuration.TypeConverterOptionsCache.GetOptions<string>().Formats = new[] { "'{0}'" };

// 流式读取所有行(延迟加载,不会一次性加载到内存)
var records = csv.GetRecords<CsvLocationRecord>();

步骤3:LINQ分组+数据整理

直接用LINQ按personal_id分组,将不同location_type对应的location_number归类到对应列表:

var groupedData = records
    .GroupBy(r => r.personal_id)
    .Select(g => new PersonalLocationResult
    {
        personal_id = g.Key,
        company = g.Where(r => r.location_type.Equals("company", StringComparison.OrdinalIgnoreCase))
                   .Select(r => r.location_number)
                   .ToList(),
        branch = g.Where(r => r.location_type.Equals("branch", StringComparison.OrdinalIgnoreCase))
                  .Select(r => r.location_number)
                  .ToList()
    })
    // 过滤空列表,和示例输出格式对齐
    .Select(result => 
    {
        if (!result.company?.Any() ?? true) result.company = null;
        if (!result.branch?.Any() ?? true) result.branch = null;
        return result;
    })
    .ToList();

步骤4:用AutoMapper简化映射(可选)

如果想用AutoMapper替代手动映射,先创建映射配置再转换:

var config = new MapperConfiguration(cfg =>
{
    cfg.CreateMap<IGrouping<int, CsvLocationRecord>, PersonalLocationResult>()
       .ForMember(dest => dest.personal_id, opt => opt.MapFrom(src => src.Key))
       .ForMember(dest => dest.company, opt => opt.MapFrom(src => src.Where(r => r.location_type == "company").Select(r => r.location_number)))
       .ForMember(dest => dest.branch, opt => opt.MapFrom(src => src.Where(r => r.location_type == "branch").Select(r => r.location_number)));
});

var mapper = config.CreateMapper();

// 用AutoMapper转换分组数据
var groupedData = records
    .GroupBy(r => r.personal_id)
    .Select(mapper.Map<PersonalLocationResult>)
    .Select(result => 
    {
        if (!result.company?.Any() ?? true) result.company = null;
        if (!result.branch?.Any() ?? true) result.branch = null;
        return result;
    })
    .ToList();

步骤5:序列化为目标格式JSON

用System.Text.Json或Newtonsoft.Json生成符合要求的JSON:

// 使用System.Text.Json
var json = JsonSerializer.Serialize(groupedData, new JsonSerializerOptions
{
    WriteIndented = true, // 格式化输出
    IgnoreNullValues = true // 忽略空属性,和示例对齐
});

// 或者使用Newtonsoft.Json
// var json = JsonConvert.SerializeObject(groupedData, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });

// 将JSON写入文件
File.WriteAllText("输出文件路径.json", json);

关键注意事项

  • 大文件适配:流式读取+LINQ延迟执行确保不会一次性加载数十万行数据到内存,避免内存溢出
  • 格式兼容:通过CSVHelper配置自动解析带单引号的location_type值
  • 输出对齐:通过忽略空属性,让最终JSON和示例格式完全一致

内容的提问来源于stack exchange,提问作者TGR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 13:50:19