2017-08-18 13 views
1

1つの列をグループ化し、既存の列のすべての値に基づいて4つの新しい列を作成するサンプルデータセットがあります。ここでgroupby/aggregateを使用して複数の列を返す

は、いくつかのサンプルデータです:

次のようになります
data = {'AlignmentId': {0: u'ENSMUST00000000001.4-1', 
    1: u'ENSMUST00000000001.4-1', 
    2: u'ENSMUST00000000003.13-0', 
    3: u'ENSMUST00000000003.13-0', 
    4: u'ENSMUST00000000003.13-0'}, 
'name': {0: u'NonCodingDeletion', 
    1: u'NonCodingInsertion', 
    2: u'CodingDeletion', 
    3: u'CodingInsertion', 
    4: u'NonCodingDeletion'}, 
'value_CDS': {0: nan, 1: nan, 2: 1.0, 3: 1.0, 4: nan}, 
'value_mRNA': {0: 21.0, 1: 26.0, 2: 1.0, 3: 1.0, 4: 2.0}} 
df = pd.DataFrame.from_dict(data) 

:私はかどうかに応じてname列の値の存在/不在に基づいてブール値を返すようにしたい

   AlignmentId    name value_mRNA value_CDS 
0 ENSMUST00000000001.4-1 NonCodingDeletion  21.0  NaN 
1 ENSMUST00000000001.4-1 NonCodingInsertion  26.0  NaN 
2 ENSMUST00000000003.13-0  CodingDeletion   1.0  1.0 
3 ENSMUST00000000003.13-0  CodingInsertion   1.0  1.0 
4 ENSMUST00000000003.13-0 NonCodingDeletion   2.0  NaN 

value_CDSにはNULL値のみが含まれています。私はそうするように、この関数を作成:

def aggfunc(s): 
    if s.value_CDS.any(): 
     c = set(s.name) 
    else: 
     c = set(s.name) 
    return ('CodingDeletion' in c or 'CodingInsertion' in c, 
      'CodingInsertion' in c, 'CodingDeletion' in c, 
      'CodingMult3Deletion' in c or 'CodingMult3Insertion' in c) 

そして、これをしなかった:

私にエラーを与える ValueError: Shape of passed values is (318, 4), indices imply (318, 3)
merged = df.groupby('AlignmentId').aggregate(aggfunc) 

groupby-aggregateから複数の新しい列を返すにはどうすればよいですか?

私が探しています出力は次のとおりです。私は、理想的に5列のデータフレームに入れてしまう

ENSMUST00000000001.4-1 (False, False, False, False) 
ENSMUST00000000003.13-0 (True, True, True, False) 

私は.applyを使用する場合は、出力が正しくありません:

ENSMUST00000000001.4-1  (False, False, False, False) 
ENSMUST00000000003.13-0 (False, False, False, False) 

しかし、私は一度にグループ1をつかむならば、それは正しいです:

In [380]: for aln_id, d in df.groupby('AlignmentId'): 
    .....:  print aggfunc(d) 
    .....: 
(False, False, False, False) 
(True, True, True, False) 

答えて

3

あなたは['name']nameを変更する必要があります、 .nameグループの戻り値(列グループ化の値):

def aggfunc(s): 
    if s.value_CDS.any(): 
     c = set(s['name']) 
    else: 
     c = set(s['name']) 

    return ('CodingDeletion' in c or 'CodingInsertion' in c, 
      'CodingInsertion' in c, 'CodingDeletion' in c, 
      'CodingMult3Deletion' in c or 'CodingMult3Insertion' in c) 

merged = df.groupby('AlignmentId').apply(aggfunc) 
print (merged) 
AlignmentId 
ENSMUST00000000001.4-1  (False, False, False, False) 
ENSMUST00000000003.13-0  (True, True, True, False) 
dtype: object 

def aggfunc(s): 

    print ('Name of group is: {}'.format((s.name))) 
    print ('Column name is:\n {}'.format(s['name'])) 


merged = df.groupby('AlignmentId').apply(aggfunc) 
print (merged) 

Name of group is: ENSMUST00000000001.4-1 
Column name is: 
0  NonCodingDeletion 
1 NonCodingInsertion 
Name: name, dtype: object 
Name of group is: ENSMUST00000000001.4-1 
Column name is: 
0  NonCodingDeletion 
1 NonCodingInsertion 
Name: name, dtype: object 
Name of group is: ENSMUST00000000003.13-0 
Column name is: 
2  CodingDeletion 
3  CodingInsertion 
4 NonCodingDeletion 
Name: name, dtype: object 

の改善コード:

def aggfunc(s): 
    #if and else return same c, so omitted 
    c = set(s['name']) 

    #added Series for return columns instead tuples 
    cols = ['col1','col2','col3','col4'] 
    return pd.Series(('CodingDeletion' in c or 'CodingInsertion' in c, 
      'CodingInsertion' in c, 'CodingDeletion' in c, 
      'CodingMult3Deletion' in c or 'CodingMult3Insertion' in c), index=cols) 

merged = df.groupby('AlignmentId').apply(aggfunc) 
print (merged) 

          col1 col2 col3 col4 
AlignmentId           
ENSMUST00000000001.4-1 False False False False 
ENSMUST00000000003.13-0 True True True False 
関連する問題