আমি কীভাবে কোনও পাঠ্য ফাইলে মোট চলমান সংখ্যাসমূহ তৈরি করতে পারি?


9

আমার কাছে 2 মিলিয়ন লাইনযুক্ত একটি পাঠ্য ফাইল রয়েছে। প্রতিটি লাইনের ইতিবাচক পূর্ণসংখ্যা থাকে। আমি ফ্রিকোয়েন্সি টেবিল ধরণের জিনিস গঠনের চেষ্টা করছি।

ইনপুট ফাইল:

3
4
5
8

আউটপুট হওয়া উচিত:

3
7
12
20

কিভাবে আমি এই কাজ সম্পর্কে যান?


1
আপনার পাঠ্যে, আপনি বলেছেন যে আপনি একটি ফ্রিকোয়েন্সি টেবিল চান । আপনার আউটপুট নমুনা একটি তালিকা। আপনি কি এই পরিষ্কার করতে পারেন?
ওয়েইন_উইক্স

প্রকৃতপক্ষে আপনার আউটপুট কোনও ফ্রিকোয়েন্সি টেবিল নয়
don.joey

আমি দুঃখিত. আমি একটি संचयी ফ্রিকোয়েন্সি টেবিল বোঝাতে চাইছি। প্রশ্ন সংশোধন করেছেন। ধন্যবাদ।

এটি খুব দুর্দান্ত নয় তবে আমি সাধারণত স্প্রেডশিটে এই জাতীয় জিনিসগুলি করি।
জন ইউ

@ জোহানু আমি সাধারণত করি তবে আমার যে ফাইলটি রয়েছে তার মিলিয়ন সংখ্যা রয়েছে।

উত্তর:


20

সাথে awk:

awk '{total += $0; $0 = total}1'

$0বর্তমান লাইন সুতরাং, প্রতিটি লাইনের জন্য, আমি এটিকে যুক্ত করব total, নতুনটিতে লাইনটি সেট করবো total, এবং তারপরে 1হ'ল একটি বিশ্রী শর্টকাট - এটি প্রতিটি সত্য শর্তের জন্য বর্তমান লাইনটি মুদ্রণ করে এবং 1শর্ত হিসাবে সত্য হিসাবে মূল্যায়ন করে।


আপনি আপনার কোড ব্যাখ্যা করতে পারেন?
জর্জ উদোসেন

শব্দটিও printকি ব্যবহার করা যায়?
জর্জ উদোসেন

হ্যাঁ, print total}পরিবর্তে$0 = total}1
muru

1
@ জর্জি আহ, না
মুড়ু

9
Awk স্ক্রিপ্ট লেখার একটি সংক্ষিপ্ত এবং সম্ভবত আরো বোধগম্য উপায় হবে{print(total += $0)}
মাইলস

9

একটি অজগর লিপি:

#!/usr/bin/env python3
import sys

f = sys.argv[1]; out = sys.argv[2]

n = 0

with open(out, "wt") as wr:
    with open(f) as read:
        for l in read:
            n = n + int(l); wr.write(str(n)+"\n")

ব্যবহার করা

  • একটি ফাঁকা ফাইলে স্ক্রিপ্টটি অনুলিপি করুন, এটি সংরক্ষণ করুন add_last.py
  • উত্স ফাইল এবং লক্ষ্যবস্তু আউটপুট ফাইলটিকে আর্গুমেন্ট হিসাবে এটি চালান:

    python3 /path/to/add_last.py <input_file> <output_file>
    

ব্যাখ্যা

কোডটি বরং পাঠযোগ্য, তবে বিস্তারিতভাবে:

  • ফলাফল লেখার জন্য আউটপুট ফাইল খুলুন

    with open(out, "wt") as wr:
    
  • প্রতি লাইনে পড়ার জন্য ইনপুট ফাইলটি খুলুন

    with open(f) as read:
        for l in read:
    
  • মোটে নতুন লাইনের মান যুক্ত করে লাইনগুলি পড়ুন:

    n = n + int(l)
    
  • ফলাফল আউটপুট ফাইলে লিখুন:

    wr.write(str(n)+"\n")
    


3
এটি স্বল্পতা বা সময়ের কার্যকারিতা সম্পর্কে নয় (মিলিয়ন লাইনগুলি বড় ডেটা নয়)। আপনার উত্তরের কোডটি অলঙ্কৃত নয়। আমার উত্তরটি আপনার আরও অজগর সংস্করণ।
jfs

8
@ জেএফএসবেস্টিয়ান যদি আরও প্রচ্ছন্ন সংস্করণটি ধীর হয় তবে কেন কেউ এটিকে পছন্দ করবেন? "পাইথোনিক" হওয়ার বিশেষ কিছু নেই যা কেবলমাত্র একটি কনভেনশন যা অজগর ডেভসকে শেয়ারযোগ্য কোড এবং পাঠযোগ্যতার জন্য মানকে সহায়তা করে। যদি আরও আইডোম্যাটিক ভার্সনটি কম দক্ষ (ধীর) হয় তবে আপনি যদি এমন পরিবেশে কাজ না করেন তবে এটি ব্যবহার করা উচিত না যেখানে পারফরম্যান্সের চেয়ে মানিককরণ বেশি গুরুত্বপূর্ণ (যা আমার কাছে ভয়ঙ্কর ধারণা বলে মনে হয়)।
টেরডন

2
@terdon অকাল অপটিমাইজেশন সম্পর্কে কিছু বলা আছে। দীর্ঘমেয়াদী রক্ষণাবেক্ষণের কারণে পঠনযোগ্যতা গুরুত্বপূর্ণ হতে পারে।
মুরু

4
@ মুরু নিশ্চিত, তবে এটি নিখুঁতভাবে পঠনযোগ্য। এটি কেবল অপরাধ "পাইথোনিক" হচ্ছে না। উল্লেখ করার দরকার নেই যে আমরা of টি লাইন কোডের কথা বলছি, কোনও বিশাল প্রকল্প নয়। স্টাইল কনভেনশনের নামে দক্ষতার ত্যাগ বলাকে ভুল পদ্ধতির মতো মনে হয়।
টেরডন

9

শুধুই মজার জন্য

$ sed 'a+p' file | dc -e0 -
3
7
12
20

এটি ইনপুটটির প্রতিটি লাইনে একটি পেপেন্ডিংয়ের মাধ্যমে কাজ করে +pএবং তারপরে ফলাফলটি dcক্যালকুলেটরে পাস করে

   +      Pops two values off the stack, adds them, and pushes the result.
          The precision of the result is determined only by the values  of
          the arguments, and is enough to be exact.

তারপর

   p      Prints  the  value on the top of the stack, without altering the
          stack.  A newline is printed after the value.

-e0যুক্তি push কর্মের 0সম্মুখের dcস্ট্যাক সমষ্টি আরম্ভ করতে।


এরকম কিছু সম্ভবত বড় ডেটাসেটের চেয়ে দ্রুততম হতে পারে
ডিজিটাল ট্রমা


একটি উত্সাহব্যঞ্জক জন্য মজাদার সমস্ত প্রয়োজন: ডি
গ্লানি

দয়া করে এটি একটু ব্যাখ্যা করুন।
আমানিকা

8

বাশে:

#! /bin/bash

file="YOUR_FILE.txt"

TOTAL=0
while IFS= read -r line
do
    TOTAL=$(( TOTAL + line ))
    echo $TOTAL
done <"$file"

বাশ real 0m53.116s
এটির

@ জ্যাকবভিলিজম ড্যাশ প্রায় দ্বিগুণ দ্রুত, ব্যস্তবক্স অ্যাশ এবং জেডএসএইচ (মোডে) 1.5 গুণ, তবে অবশ্যই ড্যাশটি পাইথনের চেয়ে 5 গুণ কম ধীর।
মুরু

6

স্ট্যান্ডার্ড ইনপুটটিতে প্রতিটি লাইনে দেওয়া পূর্ণসংখ্যার আংশিক পরিমাণ প্রিন্ট করতে:

#!/usr/bin/env python3
import sys

partial_sum = 0
for n in map(int, sys.stdin):
    partial_sum += n
    print(partial_sum)

চলমান উদাহরণ

যদি কোনও কারণে কমান্ডটি খুব ধীর হয়; আপনি সি প্রোগ্রাম ব্যবহার করতে পারেন:

#include <stdint.h>
#include <ctype.h>
#include <stdio.h>

int main(void)
{
  uintmax_t cumsum = 0, n = 0;
  for (int c = EOF; (c = getchar()) != EOF; ) {
    if (isdigit(c))
      n = n * 10 + (c - '0');
    else if (n) { // complete number
      cumsum += n;
      printf("%ju\n", cumsum);
      n = 0;
    }
  }
  if (n)
    printf("%ju\n", cumsum + n);
  return feof(stdin) ? 0 : 1;
}

এটি তৈরি এবং চালানোর জন্য, টাইপ করুন:

$ cc cumsum.c -o cumsum
$ ./cumsum < input > output

চলমান উদাহরণ

UINTMAX_MAXহয় 18446744073709551615

সি কোডটি আমার মেশিনে অর্ডিক কমান্ডের চেয়ে কয়েকগুণ দ্রুত ইনপুট ফাইলের দ্বারা উত্পাদিত হয়:

#!/usr/bin/env python3
import numpy.random
print(*numpy.random.random_integers(100, size=2000000), sep='\n')


5

আপনি সম্ভবত এরকম কিছু চান:

sort -n <filename> | uniq -c | awk 'BEGIN{print "Number\tFrequency"}{print $2"\t"$1}'

আদেশের ব্যাখ্যা:

  • sort -n <filename> | uniq -c ইনপুট বাছাই করে এবং একটি ফ্রিকোয়েন্সি টেবিল ফেরত দেয়
  • | awk 'BEGIN{print "Number\tFrequency"}{print $2"\t"$1}' আউটপুটটিকে আরও ভাল ফর্ম্যাটে রূপান্তরিত করে

উদাহরণ:
ইনপুট ফাইল list.txt:

4
5
3
4
4
2
3
4
5

আদেশ:

$ sort -n list.txt | uniq -c | awk 'BEGIN{print "Number\tFrequency"}{print $2"\t"$1}'
Number  Frequency
2   1
3   2
4   4
5   2

আমি এই
আউটপুটটি

5

আপনি এই vim করতে পারেন। ফাইলটি খুলুন এবং নিম্নলিখিত কীস্ট্রোকগুলি টাইপ করুন:

qaqqayiwj@"<C-a>@aq@a:wq<cr>

লক্ষ্য করুন <C-a>আসলে Ctrl-একটি, এবং <cr>হয় গাড়ি ফেরত , অর্থাত্ বোতাম লিখুন।

এটি কীভাবে কাজ করে তা এখানে। প্রথমে, আমরা 'এ' রেজিস্টারটি পরিষ্কার করতে চাই যাতে এটির প্রথমবারের মতো কোনও পার্শ্ব প্রতিক্রিয়া না ঘটে। এটি সহজভাবে qaq। তারপরে আমরা নিম্নলিখিতটি করি:

qa                  " Start recording keystrokes into register 'a'
  yiw               " Yank this current number
     j              " Move down one line. This will break the loop on the last line
      @"            " Run the number we yanked as if it was typed, and then
        <C-a>       " increment the number under the cursor *n* times
             @a     " Call macro 'a'. While recording this will do nothing
               q    " Stop recording
                @a  " Call macro 'a', which will call itself creating a loop

এই পুনরাবৃত্ত ম্যাক্রো চলমান হয়ে যাওয়ার পরে, আমরা কেবল :wq<cr>সংরক্ষণ এবং প্রস্থান করার জন্য কল করি ।


1
যাদু জাদু ভেঙে ফেলা এবং সমস্ত অংশ ব্যাখ্যা করার জন্য +1। এই অংশগুলি খুব দূরে বিরল।
জন ইউ

5

পার্ল ওয়ান-লাইনার:

$ perl -lne 'print $sum+=$_' input.txt                                                                
3
7
12
20

সংখ্যাটির 2.5 মিলিয়ন লাইনের সাথে, এটি প্রক্রিয়া করতে প্রায় 6.6 সেকেন্ড সময় নেয়:

$ time perl -lne 'print $sum+=$_' large_input.txt > output.txt                                        
    0m06.64s real     0m05.42s user     0m00.09s system

$ wc -l large_input.txt
2500000 large_input.txt

real 0m0.908s, অনেক ভালো.
জ্যাকব Vlijm

@ জ্যাকবভিলিজম এটি একটি খুব ছোট ফাইলের উপর। আমি 2.5 মিলিয়ন লাইনের ফাইল সহ একটি ছোট পরীক্ষা যুক্ত করেছি। 6.64 সেকেন্ড
সের্গেই কোলডিয়াজহনি

1
আমি একটি প্রাচীন সিস্টেমে 1.3 মিলিয়ন লাইনে
দৌড়েছি

3

একটি সাধারণ ব্যাশ ওয়ান-লাইনার:

x=0 ; while read n ; do x=$((x+n)) ; echo $x ; done < INPUT_FILE

xবর্তমান লাইন এবং উপরের সমস্ত সংখ্যার সংখ্যার যোগফল।
nবর্তমান লাইনে নম্বর।

আমরা সব লাইনের উপর লুপ nএর INPUT_FILEএবং আমাদের পরিবর্তনশীল তাদের সাংখ্যিক মান যোগ xএবং প্রতিটি পুনরাবৃত্তির সময় যে সমষ্টি প্রিন্ট করা হবে।

বাশ এখানে কিছুটা ধীর হলেও আপনি কনসোলে আউটপুট প্রিন্ট না করেই 2 মিলিয়ন এন্ট্রি সহ কোনও ফাইলের জন্য এটি প্রায় 20-30 সেকেন্ডের জন্য চালানোর আশা করতে পারেন (এটি আপনি যে পদ্ধতিটি ব্যবহার করেন তা ধীরে ধীরে স্বতন্ত্র)।


3

@ স্টিল্ড্রাইভারের উত্তরের মতো, তবে bcপরিবর্তে সামান্য কম আরকেন সহ :

sed 's/.*/a+=&;a/' input | bc

bc(এবং dc) সম্পর্কে দুর্দান্ত জিনিসটি হ'ল এগুলি নির্বিচারে নির্ভুলতা ক্যালকুলেটর, সুতরাং কখনই উপচে পড়বে না বা পূর্ণসংখ্যার চেয়ে নির্ভুলতার অভাব ভোগ করবে না।

sedঅভিব্যক্তি ইনপুট রূপান্তরিত:

a+=3;a
a+=4;a
a+=5;a
a+=8;a

এটি তখন দ্বারা মূল্যায়ন করা হয় bcaখ্রিস্টপূর্ব পরিবর্তনশীল স্বয়ংক্রিয় ইনিশিয়ালাইজ প্রতিটি লাইন বাড়তি 0. হয় a, তারপর স্পষ্টভাবে এটি ছাপে।


real 0m5.642s1.3 মিলিয়ন লাইনে সেড এই সত্যিই ধীর।
জ্যাকব Vlijm
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.