代码有什么问题。它存储空矩阵,但很少打印“,”

时间:2019-12-23 11:27:03

标签: python pandas numpy

import pandas as pd
import numpy as np
df1 = pd.read_csv("D:\PHD\obranking\demo.csv")

Mat = np.empty((300, 300), dtype=str)
for i in range(1,5502):
    for j in range(0,300):
        for k in range(0,300):
            if df1['label'][j] != df1['label'][k]:
                if df1[df1.columns[i]][j] != df1[df1.columns[i]][k]:
                    Mat[j][k] = Mat[j][k] + "," + df1.columns[i]
np.save("D:\PHD\obranking\MatDemo", Mat)

PS:df1.columns[i]具有作为字符串的值。并非每次都为空

1 个答案:

答案 0 :(得分:1)

您的原始dtype:

In [16]: arr = np.empty((2,), dtype=str)                                        
In [17]: arr                                                                    
Out[17]: array(['', ''], dtype='<U1')    # str is equivalent to U1 - 1 char string

尝试添加字符串:

In [18]: arr[0] += ','+'foobar'                                                 
In [19]: arr                                                                    
Out[19]: array([',', ''], dtype='<U1')

只有1个字符的空间,因此我们只用逗号即可。有人抱怨这种截断。有些人认为numpy应该引发错误或扩展dtype。

更好,让我们从更长的dtype开始:

In [20]: arr = np.empty((2,), dtype='U10')                                      
In [21]: arr                                                                    
Out[21]: array(['', ''], dtype='<U10')    
In [22]: arr[0] += ','+'foobar'                                                 
In [23]: arr                                                                    
Out[23]: array([',foobar', ''], dtype='<U10')    # now we see the full addition
In [24]: arr[0] += ','+'foobar'                                                 
In [25]: arr                                                                    
Out[25]: array([',foobar,fo', ''], dtype='<U10')  # but still get truncation

您的下一次尝试:

In [26]: arr = np.empty((2,), dtype=object)                                     
In [27]: arr                                                                    
Out[27]: array([None, None], dtype=object)   # note the initial fill value

In [28]: arr[0] += ','+'foobar'                                                 
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-28-2c5ca97a0fa9> in <module>
----> 1 arr[0] += ','+'foobar'

TypeError: unsupported operand type(s) for +=: 'NoneType' and 'str'

在这两种情况下,如果您一开始都看过Mat,或者测试了一个如我所示的小例子,您可能已经发现了问题。从小的测试用例开始,在每个步骤中检查值。如果不适用于一个案例,尝试使用300x300案例毫无意义。

但是,如果我们以空白字符串开头(这与U1U10 numpy字符串类型不同):

In [29]: arr[0] = ''                                                            
In [30]: arr                                                                    
Out[30]: array(['', None], dtype=object)
In [31]: arr[0] += ','+'foobar'                                                 
In [32]: arr                                                                    
Out[32]: array([',foobar', None], dtype=object)
In [33]: arr[0] += ','+'foobar'                                                 
In [34]: arr                                                                    
Out[34]: array([',foobar,foobar', None], dtype=object)

pandas已选择绕过numpy字符串dtypes,而是将字符串存储为对象,即Python字符串。 numpy方法在内存方面更有效,至少在字符串都大小相同的情况下。但是,如果它们的大小差异很大,或者需要像这样增长,则对象dtype更好。

在您的情况下,您从pandas及其对象字符串开始,并将大量但可变数量的字符串添加到数组中。坚持使用对象dtype可能是最好的。但要注意开头的None

另一种方法是收集列表中的字符串:

In [35]: arr[1]=[]                                                              
In [36]: arr                                                                    
Out[36]: array([',foobar,foobar', list([])], dtype=object)
In [37]: arr[1].append('foobar')                                                
In [38]: arr[1].append('foobar')                                                
In [39]: arr                                                                    
Out[39]: array([',foobar,foobar', list(['foobar', 'foobar'])], dtype=object)
In [40]: arr[1]=','.join(arr[1])                                                
In [41]: arr                                                                    
Out[41]: array([',foobar,foobar', 'foobar,foobar'], dtype=object)

列表追加比字符串连接更有效,并且join将分隔符放在字符串之间做得更干净。

对象dtype数组本质上和处理上都接近列表。它没有我们用数字dtype看到的快速处理。