質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

Spark

Spark(Apache Spark)とは、膨大なデータを迅速、柔軟に分散並行処理を行うフレームワークです。分析ツールであるApache Hadoopと比較し、最大で100倍の速度でデータ処理ができるとされています。

Q&A

解決済

2回答

1071閲覧

カテゴリごとにRow数を調整(削除)する

sasakin

総合スコア15

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

Spark

Spark(Apache Spark)とは、膨大なデータを迅速、柔軟に分散並行処理を行うフレームワークです。分析ツールであるApache Hadoopと比較し、最大で100倍の速度でデータ処理ができるとされています。

0グッド

1クリップ

投稿2021/05/14 01:41

やりたい事

下のようなカテゴリ属性をもつ、データフレームがあるとして、(例のためpandasデータフレームで作成しています)

import pandas as pd df= pd.DataFrame({ '場所':['東京','大阪','京都','神奈川','東京','東京','京都','神奈川'], '他属性1':['a','a','a','a','a','a','a','a'], '他属性2':['a','a','a','a','a','a','a','a'], })

場所 他属性1 他属性2
0 東京 a a
1 大阪 a a
2 京都 a a
3 神奈川 a a
4 東京 a a
5 東京 a a
6 京都 a a
7 神奈川 a a

これらの件数を下のデータフレームを参考に各カテゴリごとに件数調整し抽出したいです。 

df = pd.DataFrame({ '場所':['東京','大阪','京都','神奈川'], '抽出件数':[2,1,1,1] })

場所 抽出件数
0 東京 2
1 大阪 1
2 京都 1
3 神奈川 1

<目標イメージ>

場所 他属性1 他属性2
0 東京 a a
1 大阪 a a
3 神奈川 a a
4 東京 a a
6 京都 a a

順番は問わず(各カテゴリごとにシャフルしたい)

課題

pysparkを使っているのですが、対象データにおけるカテゴリ数が多く、以下のような一つずつするのは避けたいです。

df_agg = df.filter(F.col('場所')=='東京') df_agg = df.filter(F.col('場所')=='大阪') df_agg = df.filter(F.col('場所')=='神奈川')

Window関数?などを使えばそのような処理ができるのでしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

bsdfan

2021/05/14 03:51

質問としては、pysparkでやる方法を聞きたいのでしょうか? pandasでもいいのでしょうか?
sasakin

2021/05/14 04:10

修正依頼ありがとうございます。 できればpysparkの方がありがたいですが、pandasでキレイにできる方法などあれば(map関数?)そちら参考にしてpysparkで実装させていただきます!
guest

回答2

0

シャッフルのために乱数の列を追加して、window内でソートして行番号と取得したい数と比較して抜き出しています。

python

1import pandas as pd 2import pyspark 3from pyspark.sql import SparkSession 4from pyspark.sql import Window 5from pyspark.sql.functions import col, rand, row_number 6 7spark = SparkSession.builder.getOrCreate() 8 9df = pd.DataFrame({ 10 '場所':['東京','大阪','京都','神奈川','東京','東京','京都','神奈川'], 11 '他属性1':['a','b','c','d','e','f','g','h'], 12 '他属性2':['a','a','a','a','a','a','a','a'], 13 }) 14 15df_num = pd.DataFrame({ 16 '場所':['東京','大阪','京都','神奈川'], 17 '抽出件数':[2,1,1,1] 18 }) 19 20sdf = spark.createDataFrame(df) 21sdf_num = spark.createDataFrame(df_num) 22 23result = (sdf 24 .join(sdf_num, ['場所'], 'left') 25 .withColumn('x', rand()) 26 .withColumn('rank', row_number().over(Window.partitionBy(col('場所')).orderBy(col('x')))) 27 .where(col('rank') <= col('抽出件数')) 28 .drop('抽出件数', 'x', 'rank')) 29 30result.show() 31#+------+-------+-------+ 32#| 場所|他属性1|他属性2| 33#+------+-------+-------+ 34#| 大阪| b| a| 35#|神奈川| h| a| 36#| 東京| f| a| 37#| 東京| e| a| 38#| 京都| c| a| 39#+------+-------+-------+

投稿2021/05/14 08:22

編集2021/05/14 08:36
bsdfan

総合スコア4567

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

以下のコードで実現できました。
多分関数でもっとシンプルに書ける気がしますが、悪くはない気がします。
※シャフルは入っていません

python

1import pandas as pd 2from pyspark.sql import SparkSession 3from pyspark.sql import functions as F 4from functools import reduce 5spark = SparkSession.builder.getOrCreate() 6df= pd.DataFrame({ 7 '場所':['東京','大阪','京都','神奈川','東京','東京','京都','神奈川'], 8 '他属性1':['a','a','a','a','a','a','a','a'], 9 '他属性2':['a','a','a','a','a','a','a','a'], 10 }) 11main_df = spark.createDataFrame(df) 12main_df.show() 13 14df = pd.DataFrame({ 15 '場所':['東京','大阪','京都','神奈川'], 16 '抽出件数':[2,1,1,1] 17 }) 18count_df = spark.createDataFrame(df) 19count_df.show() 20 21filter_df_list = [main_df.filter(F.col('場所') == row.場所).limit(row.抽出件数) for row in count_df.collect()] 22reduce(lambda x,y: x.union(y), filter_df_list).show()

投稿2021/05/14 05:44

yamap55

総合スコア1376

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問