在pandas DataFrame中向左移动非空单元格

Lel*_*uch 5 python pandas

假设我有表格的数据

Name    h1    h2    h3    h4
A       1     nan   2     3
B       nan   nan   1     3
C       1     3     2     nan
Run Code Online (Sandbox Code Playgroud)

我想将所有非纳米细胞向左移动(或收集新列中的所有非纳米数据),同时保持从左到右的顺序,

Name    h1    h2    h3    h4
A       1     2     3     nan
B       1     3     nan   nan
C       1     3     2     nan
Run Code Online (Sandbox Code Playgroud)

我当然可以一行一行地这样做.但我希望知道是否还有其他方法可以提高性能.

su7*_*u7k 6

首先,做功能.

        def squeeze_nan(x):
            original_columns = x.index.tolist()

            squeezed = x.dropna()
            squeezed.index = [original_columns[n] for n in range(squeezed.count())]

            return squeezed.reindex(original_columns, fill_value=np.nan)
Run Code Online (Sandbox Code Playgroud)

其次,应用该功能.

df.apply(squeeze_nan, axis=1)
Run Code Online (Sandbox Code Playgroud)

您也可以尝试使用axis = 0.[:: - 1]将nan压缩到任何方向.

[编辑]

@ Mxracer888你想要这个吗?

def squeeze_nan(x, hold):
    if x.name not in hold:
        original_columns = x.index.tolist()

        squeezed = x.dropna()
        squeezed.index = [original_columns[n] for n in range(squeezed.count())]

        return squeezed.reindex(original_columns, fill_value=np.nan)
    else:
        return x

df.apply(lambda x: squeeze_nan(x, ['B']), axis=1)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


Pau*_*l H 4

这就是我所做的:

我将您的数据框分解为更长的格式,然后按名称列分组。在每个组中,我删除 NaN,但然后重新索引到完整的 h1 和 h4 集,从而在右侧重新创建 NaN。

from io import StringIO
import pandas

def defragment(x):
    values = x.dropna().values
    return pandas.Series(values, index=df.columns[:len(values)])

datastring = StringIO("""\
Name    h1    h2    h3    h4
A       1     nan   2     3
B       nan   nan   1     3
C       1     3     2     nan""")

df = pandas.read_table(datastring, sep='\s+').set_index('Name')
long_index = pandas.MultiIndex.from_product([df.index, df.columns])

print(
    df.stack()
      .groupby(level='Name')
      .apply(defragment)
      .reindex(long_index)  
      .unstack()  
)
Run Code Online (Sandbox Code Playgroud)

所以我得到:

   h1  h2  h3  h4
A   1   2   3 NaN
B   1   3 NaN NaN
C   1   3   2 NaN
Run Code Online (Sandbox Code Playgroud)