web-dev-qa-db-ja.com

パンダで列をマージ/組み合わせる方法は?

4つの列を持つ(例-)データフレームがあります。

data = {'A': ['a', 'b', 'c', 'd', 'e', 'f'],
    'B': [42, 52, np.nan, np.nan, np.nan, np.nan],  
    'C': [np.nan, np.nan, 31, 2, np.nan, np.nan],
    'D': [np.nan, np.nan, np.nan, np.nan, 62, 70]}
df = pd.DataFrame(data, columns = ['A', 'B', 'C', 'D'])

    A   B       C       D
0   a   42.0    NaN     NaN
1   b   52.0    NaN     NaN
2   c   NaN     31.0    NaN
3   d   NaN     2.0     NaN
4   e   NaN     NaN     62.0
5   f   NaN     NaN     70.0

次の例のように、列B、C、Dを新しい列Eにマージ/結合したいと思います。

data2 = {'A': ['a', 'b', 'c', 'd', 'e', 'f'],
    'E': [42, 52, 31, 2, 62, 70]}
df2 = pd.DataFrame(data2, columns = ['A', 'E'])

    A   E
0   a   42
1   b   52
2   c   31
3   d   2
4   e   62
5   f   70

私は非常によく似た質問 here を見つけましたが、これは列Aの最後にマージされた列B、C、およびDを追加します。

0      a
1      b
2      c
3      d
4      e
5      f
6     42
7     52
8     31
9      2
10    62
11    70
dtype: object

手伝ってくれてありがとう。

10
mati

オプション1
assignおよびdropの使用

In [644]: cols = ['B', 'C', 'D']

In [645]: df.assign(E=df[cols].sum(1)).drop(cols, 1)
Out[645]:
   A     E
0  a  42.0
1  b  52.0
2  c  31.0
3  d   2.0
4  e  62.0
5  f  70.0

オプション2
割り当てとdropの使用

In [648]: df['E'] = df[cols].sum(1)

In [649]: df = df.drop(cols, 1)

In [650]: df
Out[650]:
   A     E
0  a  42.0
1  b  52.0
2  c  31.0
3  d   2.0
4  e  62.0
5  f  70.0

オプション最近、3番目のオプションが好きです。
groupbyの使用

In [660]: df.groupby(np.where(df.columns == 'A', 'A', 'E'), axis=1).first() #or sum max min
Out[660]:
   A     E
0  a  42.0
1  b  52.0
2  c  31.0
3  d   2.0
4  e  62.0
5  f  70.0

In [661]: df.columns == 'A'
Out[661]: array([ True, False, False, False], dtype=bool)

In [662]: np.where(df.columns == 'A', 'A', 'E')
Out[662]:
array(['A', 'E', 'E', 'E'],
      dtype='|S1')
7
Zero

書かれた質問は合計ではなくマージ/結合を求めているので、この回答を見つけた人が、combine_firstとの結合に関するヘルプを探すのに役立つようにこれを投稿します。

df2 = pd.concat([df["A"], 
             df["B"].combine_first(df["C"]).combine_first(df["D"])], 
            axis=1)
df2.rename(columns={"B":"E"}, inplace=True)
   A     E
0  a  42.0
1  b  52.0
2  c  31.0
3  d  2.0 
4  e  62.0
5  f  70.0

何がそんなにトリッキーですか?この場合は問題ありません。ただし、a、b、c、d、e、fラベルが存在するが、必ずしも同じ順序であるとは限らない、異なるデータフレームからB、C、Dの値をプルしているとしましょう。 Combine_first()はインデックスに位置合わせするため、df参照のそれぞれにset_index()を追加する必要があります。

df2 = pd.concat([df.set_index("A", drop=False)["A"], 
             df.set_index("A")["B"]\
             .combine_first(df.set_index("A")["C"])\
             .combine_first(df.set_index("A")["D"]).astype(int)], 
            axis=1).reset_index(drop=True)
df2.rename(columns={"B":"E"}, inplace=True)

   A   E
0  a  42
1  b  52
2  c  31
3  d  2 
4  e  62
5  f  70
2
j_overTho

differenceのない列名には A を使用し、sumまたはmaxを取得します。

cols = df.columns.difference(['A'])
df['E'] = df[cols].sum(axis=1).astype(int)
# df['E'] = df[cols].max(axis=1).astype(int)
df = df.drop(cols, axis=1)
print (df)
   A   E
0  a  42
1  b  52
2  c  31
3  d   2
4  e  62
5  f  70

行ごとに複数の値がある場合:

data = {'A': ['a', 'b', 'c', 'd', 'e', 'f'],
    'B': [42, 52, np.nan, np.nan, np.nan, np.nan],  
    'C': [np.nan, np.nan, 31, 2, np.nan, np.nan],
    'D': [10, np.nan, np.nan, np.nan, 62, 70]}
df = pd.DataFrame(data, columns = ['A', 'B', 'C', 'D'])

print (df)
   A     B     C     D
0  a  42.0   NaN  10.0
1  b  52.0   NaN   NaN
2  c   NaN  31.0   NaN
3  d   NaN   2.0   NaN
4  e   NaN   NaN  62.0
5  f   NaN   NaN  70.0

cols = df.columns.difference(['A'])
df['E'] = df[cols].apply(lambda x: ', '.join(x.dropna().astype(int).astype(str)), 1)
df = df.drop(cols, axis=1)
print (df)
   A       E
0  a  42, 10
1  b      52
2  c      31
3  d       2
4  e      62
5  f      70
1
jezrael

ffillilocとともに使用することもできます。

df['E'] = df.iloc[:, 1:].ffill(1).iloc[:, -1].astype(int)
df = df.iloc[:, [0, -1]]

print(df)

   A   E
0  a  42
1  b  52
2  c  31
3  d   2
4  e  62
5  f  70
0
jpp