Моя цель состоит в том, чтобы генерировать предложения на основе частоты ввода.Например, у меня есть такой ввод:
>>> df = pd.DataFrame({"s":["a", "a", "b", "b", "c", "c"], "m":[["x", "y"], ["x", "z"], ["y", "w", "z"], ["y"], ["z"], ["z"]]})
>>> df.set_index("s")
>>> df
m
s
a [x, y]
a [x, z]
b [y, w, z]
b [y]
c [z]
c [z]
Я хочу иметь функцию gen_sentence(s)
, которая принимает s
и генерирует случайное непустое предложение на основе частоты букв в столбце m
.Поэтому gen_sentence("a")
должен генерировать предложения, в которых все они будут содержать x
, 50% из них должны содержать y
и 50% z
.
Моя интуиция заключается в том, чтобы преобразовать DataFrame в DataFrameчастота, так что для примера что-то вроде этого:
w x y z
s
a 0.0 1 0.5 0.5
b 0.5 0 1.0 0.5
c 0.0 0 0.0 1.0
И затем бросить случайное число для каждого столбца с учетом s
:
def gen_sentence(fdf, s):
return fdf.columns[np.random.random(len(fdf.columns)) < fdf.loc[s]]
Однако у меня естьне знаю, как преобразовать DataFrame в частоту DataFrame.
Решение, вероятно, будет заключаться в использовании df.agg["s"]
, но какую функцию я применяю к агрегату?
На самом деленабор данных довольно большой, более 1 миллиона строк, около 500 различных слов в m
и около 100 различных значений для s
, а таблица частот будет разреженной: большинство s
имеют нулевую частоту для большинства слов вm
.Кроме того, мне нужно сгенерировать как минимум пару сотен тысяч предложений, поэтому я пытаюсь найти реализацию, которая может генерировать предложение как можно быстрее.Кроме того, решение не должно использовать Panda, я просто думал, что векторизованная реализация большинства его функций является самым быстрым решением.
Итак, кратко , сначалаКак преобразовать DataFrame в частоту DataFrame и, во-вторых, есть ли более быстрый способ генерации предложений?
Я проверил свою реализацию, чтобы убедиться, что она достаточно быстрая и приемлемая: частотаDataFrame с 500 строками и 100 столбцами может генерировать 5000 предложений примерно за 1,2 секунды на моем компьютере.
Если вы хотите проверить свой собственный метод на моем, вот мой тест:
import timeit
setup = '''
import pandas as pd
import numpy as np
def val():
v = np.random.normal(0, 0.2)
return v if 0 <= v <= 1 else 0
def gen_sentence(fdf, s):
return fdf.columns[np.random.random(len(fdf.columns)) < fdf.loc[s]]
n = 500
m = 100
fdf = pd.DataFrame([[val() for _ in range(n)] for _ in range(m)])
fdf = fdf.join(pd.DataFrame({"s": [i for i in range(m)]}))
fdf = fdf.set_index("s")
fdf.columns = ["w%d" % i for i in range(n)]
'''
test = "x = np.random.randint(0, m); gen_sentence(fdf, x)"
print(timeit.timeit(test, setup=setup, number=5000))