簡體   English   中英

如果所有行的列中只有一個值,則折疊 Pandas 數據框中的行

[英]Collapsing rows in a Pandas dataframe if all rows have only one value in their columns

我有以下 DF

         col1  |  col2   | col3   | col4   | col5  | col6
    0    -     |   15.0  |  -     |  -     |   -   |  -
    1    -     |   -     |  -     |  -     |   -   |  US
    2    -     |   -     |  -     |  Large |   -   |  -
    3    ABC1  |   -     |  -     |  -     |   -   |  -
    4    -     |   -     |  24RA  |  -     |   -   |  -
    5    -     |   -     |  -     |  -     |   345 |  -

我想將行折疊為一,如下所示

    output DF:
         col1  |  col2    | col3   | col4   | col5  | col6
    0    ABC1  |   15.0   |  24RA  |  Large |   345 |  US

我不想遍歷列,但想使用 Pandas 來實現這一點。

選項 0
超級簡單

pd.concat([pd.Series(df[c].dropna().values, name=c) for c in df], axis=1)

   col1  col2  col3   col4   col5 col6
0  ABC1  15.0  24RA  Large  345.0   US

我們可以處理每一列多個值嗎?
我們當然可以!

df.loc[2, 'col3'] = 'Test'

   col1  col2  col3   col4   col5 col6
0  ABC1  15.0  Test  Large  345.0   US
1   NaN   NaN  24RA    NaN    NaN  NaN

選項1
像外科醫生一樣使用np.where通用解決方案

v = df.values
i, j = np.where(np.isnan(v))

s = pd.Series(v[i, j], df.columns[j])

c = s.groupby(level=0).cumcount()
s.index = [c, s.index]
s.unstack(fill_value='-')  # <-- don't fill to get NaN

   col1  col2  col3   col4 col5 col6
0  ABC1  15.0  24RA  Large  345   US

df.loc[2, 'col3'] = 'Test'

v = df.values
i, j = np.where(np.isnan(v))

s = pd.Series(v[i, j], df.columns[j])

c = s.groupby(level=0).cumcount()
s.index = [c, s.index]
s.unstack(fill_value='-')  # <-- don't fill to get NaN

   col1  col2  col3   col4 col5 col6
0  ABC1  15.0  Test  Large  345   US
1     -     -  24RA      -    -    -

選項 2
mask使空值然后stack以擺脫它們

或者我們可以

# This should work even if `'-'` are NaN
# but you can skip the `.mask(df == '-')`
s = df.mask(df == '-').stack().reset_index(0, drop=True)
c = s.groupby(level=0).cumcount()
s.index = [c, s.index]
s.unstack(fill_value='-')

   col1  col2  col3   col4 col5 col6
0  ABC1  15.0  Test  Large  345   US
1     -     -  24RA      -    -    -

您可以使用max ,但您需要轉換字符串值列中的空值(不幸的是,這有點難看)

>>> df = pd.DataFrame({'col1':[np.nan, "ABC1"], 'col2':[15.0, np.nan]})

>>> df.apply(lambda c: c.fillna('') if c.dtype is np.dtype('O') else c).max()
col1    ABC1
col2      15
dtype: object

您也可以結合使用 backfill 和 forwardfill 來填補空白,如果只想將其應用於您的某些列,這可能很有用:

>>> df.apply(lambda c: c.fillna(method='bfill').fillna(method='ffill'))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM