大数据面试离线数仓之行转列,列转行的思路是什么

行转列和列转行是离线数仓中常用的数据转换技巧,主要用于将数据从一种格式转换为另一种格式,以便更好地进行数据分析和建模。
行转列(Transpose):将一行数据转换为多行数据。这种操作通常用于将宽表(有很多列)转换为长表(有很多行),以便更容易进行数据处理。具体操作步骤如下:
a. 确定需要转换的列。
b. 使用聚合函数(如 GROUP BY、聚合查询等)将数据按照某个字段(如时间、地区等)进行分组。
c. 对每个分组应用适当的聚合函数(如 COUNT、SUM、AVG 等),将多个列的数据合并为一个或多个列。
d. 使用 PIVOT 语句(或类似的函数,如 CASE、IF 等)将分组后的数据进行行转列操作。
列转行(Pivot):将多行数据转换为一行数据。这种操作通常用于将长表(有很多行)转换为宽表(有很多列),以便更容易进行数据分析。具体操作步骤如下:
a. 确定需要转换的行。
b. 使用聚合函数(如 GROUP BY、聚合查询等)将数据按照某个字段(如时间、地区等)进行分组。
c. 对每个分组应用适当的聚合函数(如 COUNT、SUM、AVG 等),将多个行数据合并为一个或多个值。
d. 使用 PIVOT 语句(或类似的函数,如 CASE、IF 等)将分组后的数据进行列转行操作。
需要注意的是,行转列和列转行操作的具体实现可能因数据库类型(如 SQL、Hive、Spark 等)和具体需求而有所不同。在实际操作中,请根据实际情况选择合适的方法和工具。

Java代码如下

转列指将一组数据中的行转换成列,列转行指将一组数据中的列转换成行。例如,将以下表格:

姓名语文成绩数学成绩
张三8085
李四7590
王五8595

行转列后得到新的表格:

姓名科目成绩
张三语文成绩80
张三数学成绩85
李四语文成绩75
李四数学成绩90
王五语文成绩85
王五数学成绩95

列转行后得到新的表格:

姓名课程成绩
张三语文成绩80
张三数学成绩85
李四语文成绩75
李四数学成绩90
王五语文成绩85
王五数学成绩95

以下是Java代码实现:

行转列:

List<Map<String,Object>> list = new ArrayList<>();
Map<String,Object> map1 = new HashMap<>();
Map<String,Object> map2 = new HashMap<>();
Map<String,Object> map3 = new HashMap<>();
map1.put("name","张三");
map1.put("chinese",80);
map1.put("math",85);
map2.put("name","李四");
map2.put("chinese",75);
map2.put("math",90);
map3.put("name","王五");
map3.put("chinese",85);
map3.put("math",95);
list.add(map1);
list.add(map2);
list.add(map3);

List<Map<String,Object>> result = new ArrayList<>();
for(Map<String,Object> map : list){
    String name = (String) map.get("name");
    Map<String,Object> chineseMap = new HashMap<>();
    chineseMap.put("name",name);
    chineseMap.put("subject","语文成绩");
    chineseMap.put("score",map.get("chinese"));
    result.add(chineseMap);

    Map<String,Object> mathMap = new HashMap<>();
    mathMap.put("name",name);
    mathMap.put("subject","数学成绩");
    mathMap.put("score",map.get("math"));
    result.add(mathMap);
}

for(Map<String,Object> map : result){
    System.out.println(map);
}

列转行:

List<Map<String,Object>> list = new ArrayList<>();
Map<String,Object> map1 = new HashMap<>();
Map<String,Object> map2 = new HashMap<>();
Map<String,Object> map3 = new HashMap<>();
map1.put("name","张三");
map1.put("chinese",80);
map1.put("math",85);
map2.put("name","李四");
map2.put("chinese",75);
map2.put("math",90);
map3.put("name","王五");
map3.put("chinese",85);
map3.put("math",95);
list.add(map1);
list.add(map2);
list.add(map3);

Map<String,Map<String,Object>> resultMap = new HashMap<>();
for(Map<String,Object> map : list){
    String name = (String) map.get("name");
    for(Map.Entry<String,Object> entry : map.entrySet()){
        String key = entry.getKey();
        Object value = entry.getValue();
        if(!key.equals("name")){
            Map<String,Object> resultMapEntry = resultMap.get(key);
            if(resultMapEntry == null){
                resultMapEntry = new HashMap<>();
            }
            resultMapEntry.put("name",name);
            resultMapEntry.put("subject",key);
            resultMapEntry.put("score",value);
            resultMap.put(key,resultMapEntry);
        }
    }
}

for(Map<String,Object> map : resultMap.values()){
    System.out.println(map);
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值