2013-06-05 29 views
6

में बदलें बूलियन सरणी की स्ट्रिंग प्रतिनिधित्व वहाँ एक देशी numpy रास्ता बूलियन्स जैसे की स्ट्रिंग अभ्यावेदन की एक सरणी परिवर्तित करने के लिए है: एक वास्तविक बूलियन सरणी मैं मास्किंग/अनुक्रमण के लिए उपयोग कर सकते हैं करने के लिएNumpy बूलियन सरणी

['True','False','True','False'] 

? मैं लूप के माध्यम से जा रहा था और सरणी का पुनर्निर्माण कर सकता था लेकिन बड़े सरणी के लिए यह धीमा है।

+0

यह एक numpy स्ट्रिंग सरणी है (अगर ऐसी बात मौजूद है) या एक अजगर स्ट्रिंग सरणी? – Eric

+0

यह एक numpy स्ट्रिंग सरणी है - अजीब, मुझे पता है। – Newmu

+1

@ न्यूमू - मुझे लगता है कि इसका समाधान पहली जगह स्ट्रिंग प्रस्तुतियों की सरणी प्राप्त करने से बचने के लिए है। आप उस सरणी से कैसे आए? शायद यही वह जगह है जहां हमें इसे अनुकूलित करने के लिए देखना शुरू कर देना चाहिए ... – mgilson

उत्तर

6

आप एक बूलियन तुलना, IIUC ऐसा करने के लिए, चाहे dtype एक स्ट्रिंग या object है सक्षम होना चाहिए:

>>> a = np.array(['True', 'False', 'True', 'False']) 
>>> a 
array(['True', 'False', 'True', 'False'], 
     dtype='|S5') 
>>> a == "True" 
array([ True, False, True, False], dtype=bool) 

या

>>> a = np.array(['True', 'False', 'True', 'False'], dtype=object) 
>>> a 
array(['True', 'False', 'True', 'False'], dtype=object) 
>>> a == "True" 
array([ True, False, True, False], dtype=bool) 
+0

+1 - तो ... सरल। – mgilson

+0

प्रसारण के चमत्कार? यह भी तेज़ है (दूसरे उत्तर से 20x तेज)। – Newmu

+0

@ न्यूमू और स्ट्रिंग इंटर्निंग, अगर मुझे गलत नहीं लगता है (कम से कम, 'ए' में सभी आइटम 'सत्य' के पास 'id()' के लिए समान मान है, जो कि सभी के लिए भी मामला है। झूठे तत्व [हालांकि, अजीब बात यह है कि 'तत्व' उन तत्वों के लिए काम नहीं करते हैं। असल में यह तब भी काम नहीं करता जब आप अपने खिलाफ एक प्रविष्टि का परीक्षण करते हैं। '[0] एक [0] 'रिटर्न' गलत है ', भले ही 'आईडी (एक [0]) == आईडी (एक [0])' 'सत्य' लौटाता है]) मेरा मानना ​​है कि इंटर्निंग यही है कि यहां समानता जांच' numpy.char.startswith() से बहुत तेज है 'हालांकि' numpy.char' में फ़ंक्शंस को numpy arrays पर तेज़ स्ट्रिंग ऑपरेशंस करना होता है। – JAB

0

क्या यह पर्याप्त है?

my_list = ['True', 'False', 'True', 'False'] 
np.array(x == 'True' for x in my_list) 

यह देशी नहीं है, लेकिन यदि आप एक गैर देशी सूची के साथ शुरू कर रहे हैं, तो वैसे भी, यह वास्तव में कोई फर्क नहीं करना चाहिए।

+1

यह लिखित रूप में काम नहीं करेगा क्योंकि numpy जनरेटर अभिव्यक्तियों के साथ अच्छी तरह से खेल नहीं है। – DSM

+0

इसे एक सूची कंप के रूप में बॉक्सिंग करता है लेकिन यह कुछ हज़ार मूल्यों के साथ सरणी के लिए डीएसएम के उत्तर से 20x धीमी है। – Newmu

2

मैं एक विधि भी तेजी से है कि मिल गया है डीएसएम, एरिक से प्रेरणा ले रहा है, हालांकि सुधार मूल्यों की छोटी सूचियों के साथ सबसे अच्छा देखा जाता है; बहुत बड़े मूल्यों पर, पुनरावृत्ति की लागत स्वयं के बजाए numpy सरणी के निर्माण के दौरान सच्चाई परीक्षण करने के लाभ से अधिक हो जाती है। is और == दोनों के साथ परीक्षण (ऐसी परिस्थितियों के लिए जहां स्ट्रिंग्स बनाम इंटर्न बनाम हो, जब वे is गैर-इंटर्न वाले तारों के साथ काम नहीं करेंगे। 'True' शायद स्क्रिप्ट में एक शाब्दिक होने जा रहा है, हालांकि इसे प्रशिक्षित किया जाना चाहिए) ने दिखाया कि == के साथ मेरा संस्करण is के मुकाबले धीमा था, यह अभी भी डीएसएम के संस्करण से बहुत तेज था।

स्थापना परीक्षण:, (बल्कि हजारों की तुलना में सैकड़ों में)

>>> timer(stateIs, 1000) 
[101.77722641656146, 100.74985342340369, 101.47228618107965] 
>>> timer(stateEq, 1000) 
[112.26464996250706, 112.50754567379681, 112.76057346127709] 
>>> timer(stateDSM, 1000) 
[155.67689949529995, 155.96820504501557, 158.32394669279802] 

छोटे स्ट्रिंग सरणियों के लिए:

import timeit 
def timer(statement, count): 
    return timeit.repeat(statement, "from random import choice;import numpy as np;x = [choice(['True', 'False']) for i in range(%i)]" % count) 

>>> stateIs = "y = np.fromiter((e is 'True' for e in x), bool)" 
>>> stateEq = "y = np.fromiter((e == 'True' for e in x), bool)" 
>>> stateDSM = "y = np.array(x) == 'True'" 
1000 आइटम के साथ

, तेजी से बयान 66% डीएसएम के समय लेने के लिए बीएसएम के 50% से कम समय:

>>> timer(stateIs, 100) 
[11.947757485669172, 11.927990253608186, 12.057855628259858] 
>>> timer(stateEq, 100) 
[13.064947253943501, 13.161545451986967, 13.30599035623618] 
>>> timer(stateDSM, 100) 
[31.270060799078237, 30.941749748808434, 31.253922641324607] 

डीएसएम के 25% से थोड़ा अधिक होने पर सूची के अनुसार 50 आइटम के साथ:

>>> timer(stateIs, 50) 
[6.856538342483873, 6.741083326021908, 6.708402786859551] 
>>> timer(stateEq, 50) 
[7.346079345032194, 7.312723444475523, 7.309259899921017] 
>>> timer(stateDSM, 50) 
[24.154247576229864, 24.173593700599667, 23.946403452288905] 

5 आइटम, डीएसएम के बारे में 11% के लिए:

>>> timer(stateIs, 5) 
[1.8826215278058953, 1.850232652068371, 1.8559381315990322] 
>>> timer(stateEq, 5) 
[1.9252821868467436, 1.894011299061276, 1.894306935199893] 
>>> timer(stateDSM, 5) 
[18.060974208809057, 17.916322392367874, 17.8379771602049] 
+1

क्या आपने देखा कि वे परिणाम में सभी 'सही' हैं? :-P – mgilson

+0

.. nonempty तार सही हैं, भले ही वे "झूठी" हैं .. – DSM

+0

@DSM मेरा नया जवाब मेरे पुराने पर एक बड़ा सुधार प्रतीत होता है। – JAB