如果所有行的列中只有一个值,则折叠 Pandas 数据框中的行
Posted
技术标签:
【中文标题】如果所有行的列中只有一个值,则折叠 Pandas 数据框中的行【英文标题】:Collapsing rows in a Pandas dataframe if all rows have only one value in their columns 【发布时间】:2017-11-03 07:36:58 【问题描述】:我有关注 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 来实现这一点。
【问题讨论】:
有效值之外的其他值是什么,文字破折号(-)?或NaN
?
它的 NaN - 我的错,为了漂亮的打印我替换了它'-'
【参考方案1】:
选项 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 - - -
选项 2mask
制作空值,然后 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 - - -
【讨论】:
谢谢@piRSquared。为简单起见(漂亮的印刷品),我在实际数据框中用“-”删除了 NaN,它是 NaN。 谢谢@piRSquared。我喜欢超级简单的,因为我知道我的 DF 在每一行中只有一个值。它有效。 这让我很沮丧,你不能只做df.max()
...我想这将很难实现,尽管可能需要更改 numpy\
如果我只想折叠那些具有单一值的列并保持其他列不变怎么办?我可以切出这些列,运行上面的折叠方法,然后加入剩余的列。有没有像上面“超级简单”这样更好的方法?
我添加了另一个选项,如果您只想填写列中的值,它可能会很好用【参考方案2】:
你可以使用max
,但是你需要转换字符串值columsn中的空值(不幸的是有点难看)
>>> 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
您也可以结合回填和前向填充来填补空白,如果只想将其应用于您的某些列,这可能会很有用:
>>> df.apply(lambda c: c.fillna(method='bfill').fillna(method='ffill'))
【讨论】:
以上是关于如果所有行的列中只有一个值,则折叠 Pandas 数据框中的行的主要内容,如果未能解决你的问题,请参考以下文章
如果在 Pandas 的任一列中找到,则删除两个 float64 值
像 Qlik 一样计算 pandas 数据框中的列中的唯一值?