この記事は、「新人クリエーションセレモニー」イベントに参加し、一緒にゴールドクリエーションの道を歩み始めました。
はじめに:最近、実際の作業でデータ処理のこのような実際的な問題に遭遇しました。LeetCode200+アルゴリズムの質問と、1年間のパンダの熟練した使用の基礎により、私はすぐにそれを完了しました。これが将来の参考のために要約です!
トピックの説明:ユーザーのグループの複数の動作の開始スケジュールと終了スケジュールを考えると、隣接する動作間に重複がある可能性があるため(つまり、次の動作の開始時刻が前の動作の終了時刻よりも早い場合があります)、対応する開始時刻と終了時刻の情報がマージされます。一般性を失うことなく、シミュレートされたサンプルデータは次のとおりです。
上記のデータ例では、ユーザーAとユーザーBの複数の動作セットの間に特定の開始時間と終了時間が重複しています。たとえば、ユーザーAの2つの動作の開始時間と終了時間は[3、6]とそれぞれ[4、7](同時に、ここでの2つの動作グループの開始時間シーケンスはまだ間違っています)、重複しているため、[3、7]に組み合わせることができます。同様に、開始と終了ユーザーBの2つの動作の時間は[4、7]と[6、8]]であり、これらを組み合わせて[4、8]にすることもできます。
上記の小さな要件を満たすために、実際には2つの小さな問題に分解できます。
- 同じユーザーの動作の複数のグループの開始時刻を指定して、開始時刻と終了時刻のサイズに従って、間隔のマージの問題を完了します。実際、これはLeetCodeからの元の質問です
写真はLeetCode56の質問のスクリーンショットから来ています
-
シングルユーザーのインターバルマージの完了に基づいて、マルチユーザーのインターバルマージと最終結果のスプライシングを処理する方法。パンダの考え方では、それは当然、グループ化のプロセスです。分割-集約(範囲結合)-結合
まず、最初の小さな問題は難しくありません。カスタム関数を直接実装できます。サンプルコードは次のとおりです。関数の通常の実行の前提は、開始が小さいものから大きいものの順に並べ替えられていることです。もちろん、この詳細はパンダにあります。実装は簡単です。
1def range_combine(starts, ends):
2 # 在starts有序的前提下,完成区间合并
3 combines = []
4 for start, end in zip(starts, ends):
5 if not combines or start > combines[-1][1]:
6 combines.append([start, end])
7 else:
8 combines[-1][1] = max(combines[-1][1], end)
9 return combines
10# 测试样例
11starts = [1, 3, 4, 8]
12ends = [2, 6, 7, 9]
13range_combine(starts, ends)
14# 输出 [[1, 2], [3, 7], [8, 9]]
复制代码
2つ目の小さな機能を実現するためには、一定のスキルが必要です。確かなことは、ユーザーのグループ化による間隔のマージを実装するには、groupby('uid')を実行する必要があり、次に各ハタでrange_combineを実行して、各ユーザーとすべてのマージされた間隔のネストされたリストを取得します。このネストされたリストを複数の行に分割するにはどうすればよいですか。これには、Pandas-explodeの便利なAPIが含まれます。これは、シーケンスを複数の行に分割します。次のexplode関数のドキュメントからわかるように、値が列のはリストタイプの要素であり、分割することができ、行の残りの要素を複数回コピーして、分割プロセスを実現できます。
さらに、各ユーザーの複数の動作の開始間隔と終了間隔を複数の行に分割するプロセスを完了することができ、具体的な実装は次のとおりです。
これまでのところ、ほとんどの関数の実装は完了しており、最後のステップのみが残っています。つまり、各ユーザーの以前のマージされた動作の開始時刻と終了時刻を、それぞれ開始時刻と終了時刻を表す2つの列に分割します。 、pd.Seriesを直接呼び出して、名前を付けるだけです。最後に、この要件に対するpandasコードの完全な実装プロセスを示します。
実用的な要件は、複数のデータ処理のヒントに対応しています。これは実際の知識です。