93660


Jupyter Notebookを使いPython3でプログラムを作成しようとしています。

行いたいことは、txtファイル内にあるヒストグラムのデータを"元の量的データにばらして"配列へ読み込むことです。  
txtファイル内には複数のヒストグラムに関する情報が記述してあります。  
1列目にはヒストグラムの名前が書いてあります。(例：Band1, Band2, Band3,・・・)  
2列目にはヒストグラムの階級値(DN)があり、  
3列目には2列目の階級値に対応する度数(Npts)が記述してあります。  
各ヒストグラムの情報は、1行改行して書き分けてあります。  
また、txtファイルは複数のスペース区切りで記述されています。  
txtファイルの内容は以下のようになっています。  
[![画像の説明をここに入力](https://i.stack.imgur.com/r68mZ.png)](https://i.stack.imgur.com/r68mZ.png)

このtxtファイルから以下のような配列を生成したいです。

[code]

    Band1[178, 179, 179, 180, 180, 180, 181, 181,・・・]
    Band2[179, 179, 179, 179, 179, 179, 180, 181, 181,・・・]
    Band3[181, 181, ・・・]
    
[/code]

以下追記

回答ありがとうございます！txtファイルの読み込み方が分かりました。  
そして、分かりにくい質問で申し訳ありません。  
私が生成したい配列は以下のようなものではなく

[code]

    Band1 [178, 179, 180, 181, 182, 183, 184, ・・・] 
    
[/code]

以下のような配列を作成したいです。

[code]

    Band1[178, 179, 179, 180, 180, 180, 181, 181,・・・] 
    
[/code]

恐らく、DN値とNpts値についてfor文を回し、Npts値の数だけ配列に同じDN値を格納していく、、、というようなプログラムになるかと考えています。
例えばDN値が198でNpts値が4の時には、配列に198という値を4個入れるようにする


CC BY-SA 4.0
2023-02-01T06:55:03.143
93656
2023-02-02T04:23:52.080
2023-02-02T04:23:52.080
55619
55619
question
python python3
pythonでtxtファイル内にあるヒストグラムのデータを量的データにばらして配列に格納したい


以下のスクリプトファイルと同じフォルダにsample.txtが存在することを前提にしています。

コードの解説はしませんので、調べてみてください。

[code]

    import pathlib
    
    txt_path = str(pathlib.Path(__file__).parent) + '\\sample.txt'
    
    data_dict = dict()
    
    with open(txt_path, "r") as f:
        datas = f.readlines()
        usage = None
        for data in datas:
            if data:
                data_head = data.split()
                if data_head:
                    if 'Histogram' in data_head:
                        pass
                    elif len(data_head) == 4:
                        usage = ''.join(data_head[:2])
                        DN, npts = list(map(int, data_head[2:]))
                        data_dict[usage] = {
                            'DN': [DN, ],
                            'Npts': [npts, ],
                        }
                    elif len(data_head) == 2:
                        DN, npts = list(map(int, data_head))
                        data_dict[usage]['DN'].append(DN)
                        data_dict[usage]['Npts'].append(npts)
    
    print(data_dict)
    
    
[/code]

結果出力

[code]

    {'Band1': {'DN': [178, 179, 180, 181, 182, 183], 'Npts': [1, 2, 3, 6, 8, 10]}, 'Band2': {'DN': [179, 180, 181], 'Npts': [6, 1, 5]}, 'Band3': {'DN': [181, 182, 183], 'Npts': [6, 8, 10]}}
    
[/code]


CC BY-SA 4.0
2023-02-01T07:30:16.520
93657
2023-02-01T07:30:16.520
32891
93656
answer


[「複数のHistogramデータを量的データに戻して二次元配列に格納したい」のコメント](https://ja.stackoverflow.com/questions/93676#comment107044_93676)から引用:

> txtファイルは複数のスペース区切りになっております。

Pandas の `pandas.read_fwf()` を使います。

[code]

    import pandas as pd
    
    df = pd.read_fwf('data.txt', header=None, names=['Band', 'DN', 'Npts'])
    band = df.query('Band != "Histogram"').ffill().astype({'DN': int, 'Npts': int})\
             .groupby('Band').apply(lambda x: x['DN'].repeat(x['Npts']).to_list()).to_dict()
    
    print(band)
    
    # {'Band 1': [178, 179, 179, 180, 180, 180, 181, 181, 181, 181, 181, 181, ...,
    #  'Band 2': [179, 179, 179, 179, 179, 179, 180, 181, 181, 181, 181, 181, ...,
    #  'Band 3': [181, 181, 181, 181, 181, 181, 182, 182, 182, 182, 182, 182, ...,]}
    
[/code]

ちなみに、Band ごとにデータフレームを分割する場合は以下の様にします。

[code]

    df = df.query('Band != "Histogram"').ffill().astype({'DN': int, 'Npts': int})
    dfx = [g.reset_index(drop=True) for _, g in df.groupby('Band')]
    
    print(dfx[0])
    print(dfx[1])
    print(dfx[2])
    
    #      Band   DN  Npts
    # 0  Band 1  178     1
    # 1  Band 1  179     2
    # 2  Band 1  180     3
    # 3  Band 1  181     6
    # 4  Band 1  182     8
    # 5  Band 1  183    10
    # 6  Band 1  184    10
    #
    #      Band   DN  Npts
    # 0  Band 2  179     6
    # 1  Band 2  180     1
    # 2  Band 2  181     5
    # 3  Band 2  182    13
    # 4  Band 2  183    21
    #
    #      Band   DN  Npts
    # 0  Band 3  181     6
    # 1  Band 3  182     8
    # 2  Band 3  183    10
    # 3  Band 3  184    10
    # 4  Band 3  185    11
    
[/code]


CC BY-SA 4.0
2023-02-01T08:01:35.630
93660
2023-02-02T04:06:06.167
2023-02-02T04:06:06.167
47127
47127
93656
answer


Python標準パッケージから groupby使う方法

  1. まず無駄な行を取り除き
  2. Histogram が記載されていない行を補完し
  3. 最後に groupbyでまとめる

( **少し更新** )

[code]

    with open(textfile) as fp:
        lst = [ln.split() for ln in fp
                    if not ln.startswith('Histogram') and ln.strip()]
    
    res = []
    for ln in lst:
        n = len(ln)
        if n > 2:
            pre = ''.join(ln[:n -2])
        res.append([pre] +ln[-2:])
    
    from itertools import groupby, repeat
    for k,g in groupby(res, key=lambda ln: ln[0]):
        print(k, sum((list(repeat(int(ln[1]), int(ln[2])))for ln in g), start=[]))
    
    # Band1 [178, 179, 179, 180, 180, 180, 181, 181, 181, 181,
    # Band2 [179, 179, 179, 179, 179, 179, 180, 181, 181, 181,
    # Band3 [181, 181, 181, 181, 181, 181, 182, 182, 182, 182,
    
[/code]


CC BY-SA 4.0
2023-02-01T09:41:18.677
93664
2023-02-01T11:57:24.250
2023-02-01T11:57:24.250
43025
43025
93656
answer