使用pandas将单行转换为NaN的稀疏矩阵

时间:2017-09-18 23:22:08

标签: python pandas dataframe nan

给出格式的数据框:

   col1  col2  col3  col4
0     1     2     3     4

我想将当前数据框中位置[0, i]的每个元素移动到新版本中的[i, i]位置。因此,对于此输入,我想要的输出将是:

   col1   col2  col3  col4    
0   1.0    NaN   NaN   NaN
1   NaN    2.0   NaN   NaN
2   NaN    NaN   3.0   NaN
3   NaN    NaN   NaN   4.0

请注意,该位置与元素本身的值无关。

我知道我可以通过调用np.diag来执行numpy,但是返回一个0的2D数组,我不能用NaN替换0,因为一些对角线值也可能被替换,如果它们是 0s。

用熊猫做最简单的方法是什么?

5 个答案:

答案 0 :(得分:4)

In [78]: import pandas as pd

In [79]: import numpy as np

In [80]: small = pd.DataFrame(np.array([[1,2,3,4]]))

In [81]: small
Out[81]:
   0  1  2  3
0  1  2  3  4

In [82]: a = np.empty((4,4))

In [83]: a.fill(np.nan)

In [84]: np.fill_diagonal(a, small)

In [85]: a
Out[85]:
array([[  1.,  nan,  nan,  nan],
       [ nan,   2.,  nan,  nan],
       [ nan,  nan,   3.,  nan],
       [ nan,  nan,  nan,   4.]])

In [86]: large = pd.DataFrame(a)

In [87]: large
Out[87]:
     0    1    2    3
0  1.0  NaN  NaN  NaN
1  NaN  2.0  NaN  NaN
2  NaN  NaN  3.0  NaN
3  NaN  NaN  NaN  4.0

答案 1 :(得分:3)

df = pd.DataFrame([[1, 2, 3, 0, 5]], columns=("col1", "col2", "col3", "col4", "col5"))
e = np.eye(df.shape[1])

<强> EDITED

e[e == 0] = np.nan
df1 = pd.DataFrame(e * df.values, columns=df.columns)

print(df1)
   col1  col2  col3  col4  col5
0   1.0   NaN   NaN   NaN   NaN
1   NaN   2.0   NaN   NaN   NaN
2   NaN   NaN   3.0   NaN   NaN
3   NaN   NaN   NaN   0.0   NaN
4   NaN   NaN   NaN   NaN   5.0

作为旁注,你不能混合nan和整数;但你可能知道,无论如何。

答案 2 :(得分:1)

# Initialize empty dataframe matrix mirror columns of `df`
df_diag = pd.DataFrame(np.NaN, columns=df.columns, index=range(len(df.columns)))

for n, v in enumerate(df.iloc[0, :]):  # enumerate each value of first row in `df`.
    df_diag.iat[n, n] = v

>>> df_diag
   col1  col2  col3  col4
0   1.0   NaN   NaN   NaN
1   NaN   2.0   NaN   NaN
2   NaN   NaN   3.0   NaN
3   NaN   NaN   NaN   4.0

您可能还希望索引匹配:

df_diag = pd.DataFrame(np.NaN, columns=df.columns, index=df.columns)
for n, v in enumerate(df.iloc[0, :]):  
    df_diag.iat[n, n] = v

>>> df_diag
      col1  col2  col3  col4
col1   1.0   NaN   NaN   NaN
col2   NaN   2.0   NaN   NaN
col3   NaN   NaN   3.0   NaN
col4   NaN   NaN   NaN   4.0

答案 3 :(得分:1)

试试这个? :)

df=pd.concat([df]*df.shape[1],axis=0,keys=df.columns)
df.reset_index(level=1,drop=True).apply(lambda x:x[x.index==x.name]).reset_index(drop=True)
Out[202]: 
   col1  col2  col3  col4
0   1.0   NaN   NaN   NaN
1   NaN   2.0   NaN   NaN
2   NaN   NaN   3.0   NaN
3   NaN   NaN   NaN   4.0

另外,正如DYZ所提到的,我想到的第一种方法是

pd.DataFrame(df.values*np.eye(df.shape[1], dtype=int),columns=df.columns).replace({0:np.nan})

答案 4 :(得分:1)

IIUIC,您可以使用理解生成器。

In [1115]: df
Out[1115]:
   col1  col2  col3  col4
0     1     2     3     4

In [1116]: pd.DataFrame({c: v} for c, v in df.iloc[0].items())
Out[1116]:
   col1  col2  col3  col4
0   1.0   NaN   NaN   NaN
1   NaN   2.0   NaN   NaN
2   NaN   NaN   3.0   NaN
3   NaN   NaN   NaN   4.0