分组和输出部分列值pandas python

时间:2016-08-03 18:38:48

标签: python pandas

我有一个示例数据集:

TsvParser tsvParser = new TsvParser(new TsvParserSettings());
List<String[]> allRows;
List<String> headerRow;
try (BufferedReader reader = new BufferedReader(new FileReader(myFile))) {
        allRows = tsvParser.parseAll((reader));
        //Removes the header row
        headerRow = Arrays.asList(allRows.remove(0));
    }
JavaPairRDD<String, MyObject> myObjectRDD = javaSparkContext
            .parallelize(allRows)
            .mapToPair(row -> new Tuple2<>(row[0], myObjectFromArray(row)));

它看起来像这样:

import pandas as pd
import re

df = {'READID': [1,2,3  ,4,5    ,6,7    ,8,9],
  'VG': ['LV5-F*01','LV5-F*01'  ,'LV5-A*02','LV5-D*01','LV5-E*01','LV5-C*01','LV5-D*01','LV5-E*01','LV5-F*01'],
  'Pro': [1,1,1,0.33,0.59,1,0.96,1,1]}

df = pd.DataFrame(df)

我想分组列&#39; VG&#39;但只有之前的部分是&#39; *&#39;对于每一行,然后按相同的值进行分组,并将它们输出到单独的文件中。

我的理念是:

  1. 对数据集进行分组&#39; df&#39;按列&#39; VG&#39;
  2. 列的每一行&#39; VG&#39;只查看&#39; *&#39;之前的部分,例如&#39; LV5-F&#39;,&#39; LV5-A&#39;,&#39; LV5-D&#39;等
  3. 再次对数据集进行分组,但这次是针对步骤2中的相同值
  4. 将每个不同的分组集输出到单独的文件中。
  5. 渴望输出,单独的文件:

    df
    Out[12]: 
         Pro    READID        VG
    0   1.00       1      LV5-F*01
    1   1.00       2      LV5-F*01
    2   1.00       3      LV5-A*02
    3   0.33       4      LV5-D*01
    4   0.59       5      LV5-E*01
    5   1.00       6      LV5-C*01
    6   0.96       7      LV5-D*01
    7   1.00       8      LV5-E*01
    8   1.00       9      LV5-F*01
    

    我的尝试:

    'LV5-F.txt':
         Pro    READID        VG
    0   1.00       1      LV5-F*01
    1   1.00       2      LV5-F*01
    8   1.00       9      LV5-F*01
    
    
    'LV5-A.txt':
         Pro    READID        VG
    2   1.00       3      LV5-A*02
    
    
    'LV5-D.txt':
         Pro    READID        VG
    3   0.33       4      LV5-D*01
    6   0.96       7      LV5-D*01
    
    
    'LV5-E.txt':
         Pro    READID        VG
    4   0.59       5      LV5-E*01
    7   1.00       8      LV5-E*01
    
    
    'LV5-C.txt':
        Pro    READID        VG
    5   1.00       6      LV5-C*01
    

    但它在&#39; .apply(lambda x:re.findall(&#39;([0-9A-Z - ] +)*&#39;,x)&#39;步骤失败了并且我不确定它为什么不起作用,因为当我在没有成为lambda函数的情况下单独运行该代码时,它运行良好。

2 个答案:

答案 0 :(得分:2)

您必须调整to_csv以下的功能以满足您的需求。特别是,不是打印,而是以某种方式提供文件名。

但我会用这种方式构建它:

def to_csv(df):
    print df.to_csv()

#    extract
#     within
#     parens
#    /------\
# r'^([^\*]+)'
#   ^ \----/
#   |   \__________________________
# match       |          |         |
# beginning  [^this]    \*        '+'
# of string  matches   have to    match
#            not this  escape *   one or more
#
df.groupby(df.VG.str.extract(r'^([^\*]+)', expand=False)).apply(to_csv)

,Pro,READID,VG
2,1.0,3,LV5-A*02

,Pro,READID,VG
2,1.0,3,LV5-A*02

,Pro,READID,VG
5,1.0,6,LV5-C*01

,Pro,READID,VG
3,0.33,4,LV5-D*01
6,0.96,7,LV5-D*01

,Pro,READID,VG
4,0.59,5,LV5-E*01
7,1.0,8,LV5-E*01

,Pro,READID,VG
0,1.0,1,LV5-F*01
1,1.0,2,LV5-F*01
8,1.0,9,LV5-F*01

答案 1 :(得分:1)

我在@piRSquared的帮助下修改了我的代码并且它有效:

df.groupby(df.VG.str.extract(r'^([^\*]+)')).apply(lambda gp: gp.to_csv('{}.txt'.format(gp.name), sep='\t', index=False))