slice df where column looks like [(A, 3), (-A, 1), (-C, 4)] 使用像所有行这样的标准 A>5 等
slice df where column looks like [(A, 3), (-A, 1), (-C, 4)] using criteria like all rows such that A>5 etc
我有一个数据框,其中有一列如下所示:
dct = {}
for x in range(0,1000000):
test = {'A': np.random.randint(1,5), '-A': np.random.randint(1,5), '-C': np.random.randint(1,5)}
dct[str(x)+'_key'] = test
df = pd.DataFrame([[d.items()] for d in dct.values()])
df.tail()
Out[208]:
0
1299995 [(A, 3), (-A, 1), (-C, 4)]
1299996 [(A, 2), (-A, 4), (-C, 1)]
1299997 [(A, 3), (-A, 1), (-C, 3)]
1299998 [(A, 2), (-A, 2), (-C, 1)]
1299999 [(A, 1), (-A, 2), (-C, 4)]
我的数据框中有大约 130 万行。还有其他专栏,但与这个问题无关。
在我的现实生活中,每行计数的总和 = 10。但我不知道如何使用 np.random.randint()
创建一个示例数据框,以满足每行的总计数必须等于10. 有效字母表是以下 (A,B,C,D,-A,-B,-C,-D)
中的任何一个。
因此,每一行都从该集合中选择,总限制为 count = 10
。所以一行可以有这样的东西:
[(A, 10)]
[(B, 3), (-D, 1), (-A, 6)]
[(A, 2), (B, 1), (-C, 2),(-D,5)]
无论如何,上面的例子 df 应该足够了。
我想要做的是能够使用类似于以下问题的标准使用此列对这个 df 进行切片:
-all rows such that the number of A > 5 AND B < 0 (or not existent) AND -D > 2
问题可以是单条件的,也可以是多条件的。
无论如何,我不确定如何有效地执行此操作,尤其是因为每一行都由元组组成。
很简单,将列转换为字典:
df[0] = df[0].apply(dict)
现在,无论您的查询是什么,您都可以将其写为:
def query(row, key, value, cond):
return eval(str(row.get(key)) + cond + str(value))
df.apply(query, key='A', value=2, cond='>', axis=1)
或简称为:
df.apply(lambda x: x[0].get('A') > 2, axis=1)
如果您可以拆分元组列,这应该可行,只需将条件替换为您的数字即可。我将这些用于示例数据:
def f(x, var):
tup_list = list(x)
for t in tup_list:
if t[0] == var:
return t[1]
return np.NaN
df.columns = ['col']
for var in ['A', '-A', 'B', '-B', 'C', '-C', 'D', '-D']:
df[var] = df['col'].apply(lambda x: f(x, var))
df2 = df.loc[(df['A'] > 3) & ((df['-A'] < 3) & (df['B'] is not np.NaN)) & (df['-C'] > 2)]
我有一个数据框,其中有一列如下所示:
dct = {}
for x in range(0,1000000):
test = {'A': np.random.randint(1,5), '-A': np.random.randint(1,5), '-C': np.random.randint(1,5)}
dct[str(x)+'_key'] = test
df = pd.DataFrame([[d.items()] for d in dct.values()])
df.tail()
Out[208]:
0
1299995 [(A, 3), (-A, 1), (-C, 4)]
1299996 [(A, 2), (-A, 4), (-C, 1)]
1299997 [(A, 3), (-A, 1), (-C, 3)]
1299998 [(A, 2), (-A, 2), (-C, 1)]
1299999 [(A, 1), (-A, 2), (-C, 4)]
我的数据框中有大约 130 万行。还有其他专栏,但与这个问题无关。
在我的现实生活中,每行计数的总和 = 10。但我不知道如何使用 np.random.randint()
创建一个示例数据框,以满足每行的总计数必须等于10. 有效字母表是以下 (A,B,C,D,-A,-B,-C,-D)
中的任何一个。
因此,每一行都从该集合中选择,总限制为 count = 10
。所以一行可以有这样的东西:
[(A, 10)]
[(B, 3), (-D, 1), (-A, 6)]
[(A, 2), (B, 1), (-C, 2),(-D,5)]
无论如何,上面的例子 df 应该足够了。
我想要做的是能够使用类似于以下问题的标准使用此列对这个 df 进行切片:
-all rows such that the number of A > 5 AND B < 0 (or not existent) AND -D > 2
问题可以是单条件的,也可以是多条件的。
无论如何,我不确定如何有效地执行此操作,尤其是因为每一行都由元组组成。
很简单,将列转换为字典:
df[0] = df[0].apply(dict)
现在,无论您的查询是什么,您都可以将其写为:
def query(row, key, value, cond):
return eval(str(row.get(key)) + cond + str(value))
df.apply(query, key='A', value=2, cond='>', axis=1)
或简称为:
df.apply(lambda x: x[0].get('A') > 2, axis=1)
如果您可以拆分元组列,这应该可行,只需将条件替换为您的数字即可。我将这些用于示例数据:
def f(x, var):
tup_list = list(x)
for t in tup_list:
if t[0] == var:
return t[1]
return np.NaN
df.columns = ['col']
for var in ['A', '-A', 'B', '-B', 'C', '-C', 'D', '-D']:
df[var] = df['col'].apply(lambda x: f(x, var))
df2 = df.loc[(df['A'] > 3) & ((df['-A'] < 3) & (df['B'] is not np.NaN)) & (df['-C'] > 2)]