تنسيق محاذاة عشري في بيثون
-
06-07-2019 - |
سؤال
هذه ينبغي كن لطيفا.
إليك صفيف بلدي (بدلاً من ذلك ، طريقة لإنشاء صفائف اختبار تمثيلية):
>>> ri = numpy.random.randint
>>> ri2 = lambda x: ''.join(ri(0,9,x).astype('S'))
>>> a = array([float(ri2(x)+ '.' + ri2(y)) for x,y in ri(1,10,(10,2))])
>>> a
array([ 7.99914000e+01, 2.08000000e+01, 3.94000000e+02,
4.66100000e+03, 5.00000000e+00, 1.72575100e+03,
3.91500000e+02, 1.90610000e+04, 1.16247000e+04,
3.53920000e+02])
أريد قائمة بالأوتار التي ستطبع فيها ' n'.join (list_o_strings):
79.9914
20.8
394.0
4661.0
5.0
1725.751
391.5
19061.0
11624.7
353.92
اريد وسادة الفضاء إلى اليسار و الحق (ولكن ليس أكثر من اللازم).
أريد صفرًا بعد العشري إذا كان هذا هو كل ما بعد العشرية.
لا أريد تدوينًا علميًا.
.. وأنا لا أريد أن أفقد أي أرقام مهمة. (في 353.980000000000000 2 ليس مهمًا)
نعم ، من الجيد أن تريد ..
بيثون 2.5 %g, %fx.x
, ، وما إلى ذلك إما أن تحيطني ، أو لا تستطيع القيام بذلك. لم أحاول import decimal
حتى الآن. لا أستطيع رؤية ذلك نومبي يفعل ذلك إما (على الرغم من array.__str__
و array.__repr__
محاذاة عشرية (ولكن في بعض الأحيان تعود العلمية).
أوه ، وسرعة التهم. أنا أتعامل مع المصفوفات الكبيرة هنا.
مقاربات الحل الحالية هي:
- إلى str (a) وحوض أقواس Numpy
- إلى str (e) كل عنصر في الصفيف والانقسام ('.') ثم الوسادة وإعادة البناء
- إلى A.Astype ('s'+str (i)) حيث أنا الحد الأقصى (len (str (a))) ، ثم الوسادة
يبدو أنه يجب أن يكون هناك بعض الحلول الجاهزة هناك ... (ولكن غير مطلوب)
فشل الاقتراح الأعلى مع متى dtype
هو float64:
>>> a
array([ 5.50056103e+02, 6.77383566e+03, 6.01001513e+05,
3.55425142e+08, 7.07254875e+05, 8.83174744e+02,
8.22320510e+01, 4.25076609e+08, 6.28662635e+07,
1.56503068e+02])
>>> ut0 = re.compile(r'(\d)0+$')
>>> thelist = [ut0.sub(r'\1', "%12f" % x) for x in a]
>>> print '\n'.join(thelist)
550.056103
6773.835663
601001.513
355425141.8471
707254.875038
883.174744
82.232051
425076608.7676
62866263.55
156.503068
المحلول
آسف ، ولكن بعد التحقيق الشامل ، لا يمكنني العثور على أي طريقة لأداء المهمة التي تحتاجها دون الحد الأدنى من المعالجة (لتجريد الأصفار الزائدة التي لا تريد رؤيتها) ؛ شيء مثل:
import re
ut0 = re.compile(r'(\d)0+$')
thelist = [ut0.sub(r'\1', "%12f" % x) for x in a]
print '\n'.join(thelist)
هو سريع وموجز ، ولكنه يكسر قيودك على كونك "خارج الجرف"-إنه ، بدلاً من ذلك ، مزيج معياري من التنسيق العام (الذي يفعل ما تريد تقريبًا ولكن يترك الصفر الذي تريد إخفاءه) و RE لإزالة الأصفار الزائدة غير المرغوب فيها. من الناحية العملية ، أعتقد أنه يفعل بالضبط ما تحتاجه ، لكن ظروفك كما هو مذكور ، على ما أعتقد ، مثبتة بشكل مفرط.
يحرر: تم تحرير السؤال الأصلي لتحديد أرقام أكثر أهمية ، ولا يتطلب أي مساحة قيادة إضافية تتجاوز ما هو مطلوب لأكبر رقم ، وتقديم مثال جديد (حيث لا يتطابق اقتراحي السابق أعلاه مع الإخراج المطلوب). من الأفضل أداء عمل إزالة المسافة البيضاء الرائدة الشائعة في مجموعة من الأوتار TextWrap.dedent - ولكن هذا يعمل على سلسلة واحدة (مع الخطوط الجديدة) في حين أن الإخراج المطلوب هو قائمة من السلاسل. لا توجد مشكلة ، سنضع الخطوط معًا ، ونلبيها ، ونقسمها مرة أخرى:
import re
import textwrap
a = [ 5.50056103e+02, 6.77383566e+03, 6.01001513e+05,
3.55425142e+08, 7.07254875e+05, 8.83174744e+02,
8.22320510e+01, 4.25076609e+08, 6.28662635e+07,
1.56503068e+02]
thelist = textwrap.dedent(
'\n'.join(ut0.sub(r'\1', "%20f" % x) for x in a)).splitlines()
print '\n'.join(thelist)
تنبعث:
550.056103
6773.83566
601001.513
355425142.0
707254.875
883.174744
82.232051
425076609.0
62866263.5
156.503068
نصائح أخرى
لا يمكن لتنسيق سلسلة Pythons بطباعة فقط العشرية اللازمة (مع ٪ G) أو استخدام مجموعة ثابتة من العشرية (مع ٪ F). ومع ذلك ، فأنت تريد طباعة العشرية الضرورية فقط ، إلا إذا كان الرقم هو رقم كامل ، فأنت تريد عرضًا عشريًا ، وهذا يجعله معقدًا.
هذا يعني أنك ستنتهي بشيء مثل:
def printarr(arr):
for x in array:
if math.floor(x) == x:
res = '%.1f' % x
else:
res = '%.10g' % x
print "%*s" % (15-res.find('.')+len(res), res)
سيؤدي ذلك أولاً إلى إنشاء سلسلة إما مع عشري واحد ، إذا كانت القيمة عبارة عن رقم كامل ، أو ستتم طباعتها باستخدام العشرية التلقائية (ولكن فقط ما يصل إلى 10 أرقام) إذا لم يكن رقمًا كسريًا. أخيرًا ، سيتم طباعته ، بحيث يتم ضبط النقطة العشرية.
ربما ، على الرغم من ذلك ، فإن Numpy يقوم بالفعل بما تريد ، لأنك عادة ما تريد أن تكون في وضع أسي إذا كانت طويلة جدًا.