私はこれを解決しようとする大きな挑戦をしています。私はこのリストのリストを持っています:
[['060710080013011', 9],
['060710080013011', 9],
['060710080013011', 9],
['060710080013011', 9],
['060710080013011', 9],
['060710080013011', 9],
['060710080013011', 9],
['060710080013011', 9],
['060710080013011', 9],
['060710080013033', 8],
['060710080013033', 8],
['060710080013033', 8],
['060710080013033', 8],
['060710080013033', 8],
['060710080013033', 8],
['060710080013033', 8],
['060710080013033', 8],
['060710080021000', 15],
['060710080021000', 15],
['060710080021000', 15],
['060710080021000', 15],
['060710080021000', 15],
['060710080021000', 15],
['060710080021000', 15],
['060710080021000', 15],
['060710080021000', 15],
['060710080021000', 15],
['060710080021000', 15],
['060710080021000', 15],
['060710080021000', 15],
['060710080021000', 15],
['060710080021000', 15]]
最初の値はIDで、2番目の値はこのIDがリストのリストに表示される回数です。問題は次のとおりです。
2番目の値が7より大きい場合、各タプルの2番目の項目ごとに値を変更する必要があります。ここに目的の出力:
[['060710080013011', 7],
['060710080013011', 7],
['060710080013011', 7],
['060710080013011', 7],
['060710080013011', 7],
['060710080013011', 7],
['060710080013011', 7],
['060710080013011_2', 2],
['060710080013011_2', 2],
['060710080013033', 7],
['060710080013033', 7],
['060710080013033', 7],
['060710080013033', 7],
['060710080013033', 7],
['060710080013033', 7],
['060710080013033', 7],
['060710080013033_2', 1],
['060710080021000', 7],
['060710080021000', 7],
['060710080021000', 7],
['060710080021000', 7],
['060710080021000', 7],
['060710080021000', 7],
['060710080021000', 7],
['060710080021000_2', 7],
['060710080021000_2', 7],
['060710080021000_2', 7],
['060710080021000_2', 7],
['060710080021000_2', 7],
['060710080021000_2', 7],
['060710080021000_2', 7],
['060710080021000_3', 1]]
上記の私の欲求の出力が表示される場合、7より大きい数を持つすべてのサブリストの2番目の項目を変更する必要があります。
説明が必要な場合は、私の第一言語は英語ではありませんが、最善を尽くすことができます。
回答 4 件
素朴な解決策は、使用することですgroupby そしてシンプルなカウンター、ここに実用的なソリューションがあります:
In [1]: from itertools import groupby In [2]: from collections import Counter In [3]: whatever = [['060710080013011', 9], ['060710080013011', 9], ['060710080013011', 9], ['060710080013011', 9], ['06071008001 ...: 3011', 9], ['060710080013011', 9], ['060710080013011', 9], ['060710080013011', 9], ['060710080013011', 9], ['06071008001 ...: 3033', 8], ['060710080013033', 8], ['060710080013033', 8], ['060710080013033', 8], ['060710080013033', 8], ['06071008001 ...: 3033', 8], ['060710080013033', 8], ['060710080013033', 8], ['060710080021000', 15], ['060710080021000', 15], ['060710080 ...: 021000', 15], ['060710080021000', 15], ['060710080021000', 15], ['060710080021000', 15], ['060710080021000', 15], ['0607 ...: 10080021000', 15], ['060710080021000', 15], ['060710080021000', 15], ['060710080021000', 15], ['060710080021000', 15], [ ...: '060710080021000', 15], ['060710080021000', 15], ['060710080021000', 15]] In [7]: counter = [] ...: # we use groupby to group the inner list by key, i.e. the first label ...: for key, grouped in groupby(whatever, lambda x: x[0]): ...: # here, we decide if we need to append the label if the item counts great than multiple of 7 ...: for idx, item in enumerate(grouped): ...: # to get the LABEL_INDEX as new keyed keyed = key if int(idx / 7) == 0 else "{}_{}".format(key, int(idx / 7) + 1) ...: counter.append(keyed) ...: # simply use a counter to re-count the new label items ...: counted = Counter(counter) ...: answer = [] ...: for keyed in sorted(counted): ...: for _ in range(counted[keyed]): ...: answer.append([keyed, counted[keyed]]) ...: ...: print(answer) ...: ...: ...: ...: [['060710080013011', 7], ['060710080013011', 7], ['060710080013011', 7], ['060710080013011', 7], ['060710080013011', 7], ['060710080013011', 7], ['060710080013011', 7], ['060710080013011_2', 2], ['060710080013011_2', 2], ['060710080013033', 7], ['060710080013033', 7], ['060710080013033', 7], ['060710080013033', 7], ['060710080013033', 7], ['060710080013033', 7], ['060710080013033', 7], ['060710080013033_2', 1], ['060710080021000', 7], ['060710080021000', 7], ['060710080021000', 7], ['060710080021000', 7], ['060710080021000', 7], ['060710080021000', 7], ['060710080021000', 7], ['060710080021000_2', 7], ['060710080021000_2', 7], ['060710080021000_2', 7], ['060710080021000_2', 7], ['060710080021000_2', 7], ['060710080021000_2', 7], ['060710080021000_2', 7], ['060710080021000_3', 1]]
# arr is the input( list of list) output = [] n = len(arr) i=0 while i<n: ID, f = arr[i] mul = 1 while mul*7 < f: if mul!=1: newID = ID + '_' + str(mul) else: newID = ID temp = [[newID,7] for j in range(7)] mul += 1 output += temp rem = f - ((mul-1)*7) newID = ID + '_' + str(mul) temp = [[newID, rem] for j in range(rem)] output += temp i += f print(output)
上記のコードは、期待どおりの出力を提供します。
私の解決策は次のようになります。
import pandas as pd df = pd.DataFrame(lst) df.columns = ['ID', 'counter'] df.counter = df.groupby('ID').cumcount() // 7 df.loc[df.counter>0, 'ID'] += '_' + (df.counter + 1)[df.counter>0].astype(str) df.counter = df.applymap(lambda id: (df.ID==id).sum())['ID']
それだけです-終了しました。
以下では、すべての手順を説明します。
パンダで処理するデータを準備するには、ライブラリをロードし、データをデータフレームに配置します。
import pandas as pd df = pd.DataFrame(lst) df.columns = ['ID', 'counter']
最初に、カウンターはデータセット内のIDの累積カウンターのモジュロ7に設定されます。これは、サイズ7のサブグループのインデックス作成に使用できます。
df['counter'] = df.groupby('ID').cumcount() // 7
これで、データセットは次のようになります。
ID counter 0 060710080013011 0 1 060710080013011 0 2 060710080013011 0 3 060710080013011 0 4 060710080013011 0 5 060710080013011 0 6 060710080013011 0 7 060710080013011 1 8 060710080013011 1 9 060710080013033 0 10 060710080013033 0 11 060710080013033 0 12 060710080013033 0 13 060710080013033 0 14 060710080013033 0 15 060710080013033 0 16 060710080013033 1 17 060710080021000 0 18 060710080021000 0 19 060710080021000 0 20 060710080021000 0 21 060710080021000 0 22 060710080021000 0 23 060710080021000 0 24 060710080021000 1 25 060710080021000 1 26 060710080021000 1 27 060710080021000 1 28 060710080021000 1 29 060710080021000 1 30 060710080021000 1 31 060710080021000 2
次に、IDを変更します。つまり、
counter>0
の場合のみ 既存のIDにアンダースコアが先行する文字列として「counter + 1」を追加します。df.loc[df.counter>0, 'ID'] += '_' + (df.counter + 1)[df.counter>0].astype(str)
カウンターを目的のIDの合計に戻すには、各要素にラムダ関数を適用し、この要素のデータセット内のすべての出現の合計を返します。
df.counter = df.applymap(lambda id: (df.ID==id).sum())['ID']
次に、データセットは次のようになります。
ID counter 0 060710080013011 7 1 060710080013011 7 2 060710080013011 7 3 060710080013011 7 4 060710080013011 7 5 060710080013011 7 6 060710080013011 7 7 060710080013011_2 2 8 060710080013011_2 2 9 060710080013033 7 10 060710080013033 7 11 060710080013033 7 12 060710080013033 7 13 060710080013033 7 14 060710080013033 7 15 060710080013033 7 16 060710080013033_2 1 17 060710080021000 7 18 060710080021000 7 19 060710080021000 7 20 060710080021000 7 21 060710080021000 7 22 060710080021000 7 23 060710080021000 7 24 060710080021000_2 7 25 060710080021000_2 7 26 060710080021000_2 7 27 060710080021000_2 7 28 060710080021000_2 7 29 060710080021000_2 7 30 060710080021000_2 7 31 060710080021000_3 1
関連した質問
- オブジェクトの2つのリストにPythonで同じタイプのオブジェクトのみが含まれているかどうかを確認する方法はありますか?
- リストスライスの問題
- デフォルトの引数が関数で渡されない場合にNoneを空のリストに変換する最もPython的な方法は?
- 2つのリストからの複数の値を含むキーを使用してdictを作成するにはどうすればよいですか?
- 断続的な変数を再利用せずに、dictキーを使用して文字列をフォーマットする効率的な方法
- モバイル数値シーケンスを実際の文に変換するのに助けが必要です
- あるリストを別のリストに追加する方法は?
- インデックスの特定の配列からリスト内の要素をポップするにはどうすればよいですか?
- リストをネストされたリストに分割する
- Python:書き込み関数:任意のテキストの平均文長を数える方法
主にコード内のいくつかの構文エラーと誤った名前の変数、あなたが要求したとおりに動作するはずです、これが動作しない場合はお知らせください。