繁体   English   中英

如何在熊猫数据框的开头插入一个迷你标识矩阵(行和列)

[英]How to insert a mini identity matrix (row and column) to the start of Panda dataframe

给定这样的数据帧:

+-----+-----+-----+------+
|  X1 | xyz | opq |  jkl |
+-----+-----+-----+------+
| abc | 0.9 | 0.0 |  0.5 |
+-----+-----+-----+------+
| efg | 0.3 | 0.0 |  0.0 |
+-----+-----+-----+------+
| lmn | 0.0 | 0.23|  0.0 |
+-----+-----+-----+------+

如何在数据帧的开头添加一个单位矩阵以获取此信息?

+-----+-----+-----+------+------+
|  X1 | <s> | opq |  jkl |  jkl |
+-----+-----+-----+------+------+
| <s> | 1.0 | 0.0 | 0.0  |  0.0 |
+-----+-----+-----+------+------+
| abc | 0.0 | 0.9 | 0.0  |  0.5 |
+-----+-----+-----+------+------+
| efg | 0.0 | 0.3 | 0.0  |  0.0 |
+-----+-----+-----+------+------+
| lmn | 0.0 | 0.0 | 0.23 |  0.0 |
+-----+-----+-----+------+------+

那将添加一个1x1矩阵,但是有一种添加nxn矩阵的方法,例如:

+-----+-----+-----+------+------+------+
|  X1 | <s> | <e> | opq  |  jkl |  jkl |
+-----+-----+-----+------+------+------+
| <s> | 1.0 | 0.0 | 0.0  |  0.0 |  0.0 |
+-----+-----+-----+------+------+------+
| <e> | 0.0 | 1.0 | 0.0  |  0.0 |  0.0 |
+-----+-----+-----+------+------+------+
| abc | 0.0 | 0.0 | 0.9  | 0.0  |  0.5 |
+-----+-----+-----+------+------+------+
| efg | 0.0 | 0.0 | 0.3  | 0.0  |  0.0 |
+-----+-----+-----+------+------+------+
| lmn | 0.0 | 0.0 | 0.0  | 0.23 |  0.0 |
+-----+-----+-----+------+------+------+

我已经试过了:

$ echo -e 'abc\txyz\t0.9\nefg\txyz\t0.3\nlmn\topq\t0.23\nabc\tjkl\t0.5\n' > test.txt
$ cat test.txt
abc xyz 0.9
efg xyz 0.3
lmn opq 0.23
abc jkl 0.5

$ python
>>> from sframe import SFrame
>>> sf = SFrame.read_csv('test.txt', header=False, delimiter='\t', column_type_hints=[unicode, unicode, float])
[INFO] sframe.cython.cy_server: SFrame v2.1 started. Logging /tmp/sframe_server_1479779504.log
>>> df = sf.to_dataframe()
>>> df
    X1   X2    X3
0  abc  xyz  0.90
1  efg  xyz  0.30
2  lmn  opq  0.23
3  abc  jkl  0.50
>>> df = df.pivot(index='X1', columns='X2', values='X3') 
>>> df
X2   jkl   opq  xyz
X1                 
abc  0.5   NaN  0.9
efg  NaN   NaN  0.3
lmn  NaN  0.23  NaN
>>> df.fillna(0) 
X2   jkl   opq  xyz
X1                 
abc  0.5  0.00  0.9
efg  0.0  0.00  0.3
lmn  0.0  0.23  0.0

首先,我添加了一个列:

>>> numrow, numcol = df.shape
>>> df.insert(0, '<s>', [0.0] * numrow)
>>> df
X2   <s>  jkl   opq  xyz
X1                      
abc  0.0  0.5  0.00  0.9
efg  0.0  0.0  0.00  0.3
lmn  0.0  0.0  0.23  0.0

然后添加行并更改df['<s>']['<s>']

>>> numrow, numcol = df.shape
>>> df.loc['<s>'] = [0.0]*numcol
>>> df
X2   <s>  jkl   opq  xyz
X1                      
abc  0.0  0.5  0.00  0.9
efg  0.0  0.0  0.00  0.3
lmn  0.0  0.0  0.23  0.0
<s>  0.0  0.0  0.00  0.0
>>> df['<s>']['<s>'] = 1.0
>>> df
X2   <s>  jkl   opq  xyz
X1                      
abc  0.0  0.5  0.00  0.9
efg  0.0  0.0  0.00  0.3
lmn  0.0  0.0  0.23  0.0
<s>  1.0  0.0  0.00  0.0

但是我仍然需要交换最后一行并将其放在第一行,并向下推表中的所有其他行。 我怎么做?

而且必须有一个更好/更容易的方法来做到这一点。

预先添加到DataFrame并不是那么简单,尤其是当您希望同时添加行和列时。

这是我能想到的最好的解决方案,希望它不会太低效,因为考虑到使用SFrame,您可能会处理大型数据集。

首先,让我们定义要优先使用的身份矩阵的大小:

# Size o
n = 2

现在,让我们使用numpy.eye创建一个新的数据numpy.eye ,在新的行和列索引之前添加现有索引。 我本可以使用numpy.identity因为您的初始数据numpy.identity是方形的,但如果不是,它将不起作用。

df2 = pd.DataFrame(np.eye(n+df.shape[0], n+df.shape[1]), 
         index=[chr(97+x) for x in (range(n))] + df.index.tolist(),
         columns=[chr(97+x) for x in (range(n))] + df.columns.tolist())
df2


       a    b  jkl  opq  xyz
a    1.0  0.0  0.0  0.0  0.0
b    0.0  1.0  0.0  0.0  0.0
abc  0.0  0.0  1.0  0.0  0.0
efg  0.0  0.0  0.0  1.0  0.0
lmn  0.0  0.0  0.0  0.0  1.0

现在我们可以将df的值分配给df2的子集

df2.ix[n:,n:] = df
df2

       a    b  jkl   opq  xyz
a    1.0  0.0  0.0  0.00  0.0
b    0.0  1.0  0.0  0.00  0.0
abc  0.0  0.0  0.5  0.00  0.9
efg  0.0  0.0  0.0  0.00  0.3
lmn  0.0  0.0  0.0  0.23  0.0

时间: df大小(100000,1000)

CPU times: user 6.82 s, sys: 4.52 s, total: 11.3 s
Wall time: 13.1 s

更新:更快

我找到了一个更快的版本:

df = pd.DataFrame(np.random.rand(100000,1000))
old_cols = df.columns.tolist()
old_index = df.index.tolist()

# Prepend rows: Create n rows and append existing df to this
df1 = pd.DataFrame(np.zeros(shape=(n, df.shape[1])),
             index=[chr(97+x) for x in (range(n))],
             columns=old_cols)
df1 = df1.append(df)

# This was slower
#df2 = pd.DataFrame(np.zeros(shape=(df1.shape[0],n)),
#             index=df1.index,
#             columns=[chr(97+x) for x in (range(n))])
#df_final = pd.concat([df2,df1], axis=1)

# Create n columns and set to zeros
for i in range(n):
    df1[chr(97+i)] = 0

# Reindex coluns in correct order
df1 = df1[[chr(97+x) for x in (range(n))] + old_cols]

# Assign identity to the top left corner
df1.iloc[:n,:n] = np.identity(n)

时间: df大小(100000,1000)

CPU times: user 2.26 s, sys: 1.35 s, total: 3.61 s
Wall time: 3.64 s

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM