Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将列中的值相乘_Python_Sqlite - Fatal编程技术网

Python 将列中的值相乘

Python 将列中的值相乘,python,sqlite,Python,Sqlite,我通过Python2.7使用sqlite3 我有一个表,我想乘以C列中的值,B列是相同的 如果这些值位于不同的列中,则会简单得多 我可以用 从表1中选择B,C1*C2 但当涉及到在一列中进行乘法时,我就不知所措了 例如,如果这是原始表 A B C 1 Mike 2.5 1 Susan 4.2 1 Patti 2.0 2 Susan 1.1 2 Patti 3.7 3 Mike 0.2 如果B列中的入口相同,那么C列中的值将相乘,因此我的输出

我通过Python2.7使用sqlite3

我有一个表,我想乘以C列中的值,B列是相同的

如果这些值位于不同的列中,则会简单得多 我可以用

从表1中选择B,C1*C2

但当涉及到在一列中进行乘法时,我就不知所措了

例如,如果这是原始表

A   B      C
1   Mike   2.5
1   Susan  4.2
1   Patti  2.0
2   Susan  1.1
2   Patti  3.7
3   Mike   0.2
如果B列中的入口相同,那么C列中的值将相乘,因此我的输出将是

A      B
Mike   0.5
Susan  4.62
Patti  7.4

正如注释中指出的,在SQLite中创建乘法的聚合函数非常困难。但是,您可以使用
itertools.groupby
执行组合和乘法运算,然后创建一个新表来解决这个问题。此答案利用上下文管理器和属性装饰器创建干净的类调用:

import sqlite3
import itertools
class UpdateTable:
   def __init__(self, *args):
     self.__dict__ = dict(zip(['table', 'filename'], args))
     self.new_table = None
   @property
   def newtable(self):
      return self.new_table
   @newtable.setter
   def newtable(self, new_table_name):
      self.new_table = new_table_name
   def __enter__(self):
       data = map(lambda (a, b, c):[b, float(c)], list(sqlite3.connect(self.filename).cursor().execute('SELECT * FROM {}'.format(self.table))))
       self.new_data = [(a, reduce(lambda x, y:x[-1]*y[-1], list(b))) for a, b in itertools.groupby(sorted(data, key=lambda x:x[0]), key=lambda x:x[0])]
       return self
   def __exit__(self):
       conn = sqlite3.connect(self.filename)
       conn.execute('CREATE TABLE {} (A text, B float)'.format(self.new_table))
       conn.executemany('INSERT INTO {} VALUES (?, ?)'.format(self.new_table), self.new_data)
       conn.commit()
       conn.close()


with UpdateTable('table', 'db_file.db') as t:
   t.newtable = 'table2'
Python3需要
functools
用于
reduce
并且与lambda元组解包不兼容

Python3版本:

import functools
import sqlite3
import itertools
class UpdateTable:
   def __init__(self, *args):
     self.__dict__ = dict(zip(['table', 'filename'], args))
     self.new_table = None
   @property
   def newtable(self):
      return self.new_table
   @newtable.setter
   def newtable(self, new_table_name):
      self.new_table = new_table_name
   def __enter__(self):
      data = map(lambda x:[x[1], float(x[-1])], list(sqlite3.connect(self.filename).cursor().execute('SELECT * FROM {}'.format(self.table))))
      self.new_data = [(a, functools.reduce(lambda x, y:x[-1]*y[-1], list(b))) for a, b in itertools.groupby(sorted(data, key=lambda x:x[0]), key=lambda x:x[0])]
      return self
   def __exit__(self):
      conn = sqlite3.connect(self.filename)
      conn.execute('CREATE TABLE {} (A text, B float)'.format(self.new_table))
      conn.executemany('INSERT INTO {} VALUES (?, ?)'.format(self.new_table), self.new_data)
      conn.commit()
      conn.close()


with UpdateTable('table', 'db_file.db') as t:
   t.newtable = 'table2'

仅使用Python,就可以查看。您可以按列
B
对查询进行排序,然后使用将查询结果分组为数据包,然后使用以下方法进行处理:


下面是一种使用带有方便分隔符的group_concat()的方法:

import sqlite3

db = sqlite3.connect(':memory:')
db.execute('create table t(A,B,C)')
db.execute('''
insert into t values
  (1,'Mike',2.5),
  (1,'Susan',4.2),
  (1,'Patti',2.0),
  (2,'Susan',1.1),
  (2,'Patti',3.7),
  (3,'Mike',0.2)
''')

for b,expr in db.execute('''select b,group_concat(c,'*') from t group by b'''):
  #print(f'{b:10s} {eval(expr):5.2f}')            #Python 3.6
  print('%-10s %5.2f' % (b,eval(expr)))            #Python 2.7

这需要一个
PRODUCT()
聚合函数(如
SUM()
,但不是加法而是乘法),但是没有这样的事情。请参阅以了解如何在SQLite中创建自定义聚合函数。我尝试了这种方法,但得到了错误“不能将序列乘以类型为“str”的非int”。你是说你复制粘贴了上述代码并得到了错误?它在Python2.7和Python3.6下工作,给出了预期的答案。尝试在
下添加一个
print(expr)
,查看表达式中是否有意外内容(在这种情况下,您需要更正数据)。我可以得到与您所说的类似错误的唯一方法是,如果列C中的任何值包含嵌套引号,例如,
(3,'Mike','0.2')
我错了,我正在将其重新表述为我自己的代码,但您的代码工作正常。
import sqlite3

db = sqlite3.connect(':memory:')
db.execute('create table t(A,B,C)')
db.execute('''
insert into t values
  (1,'Mike',2.5),
  (1,'Susan',4.2),
  (1,'Patti',2.0),
  (2,'Susan',1.1),
  (2,'Patti',3.7),
  (3,'Mike',0.2)
''')

for b,expr in db.execute('''select b,group_concat(c,'*') from t group by b'''):
  #print(f'{b:10s} {eval(expr):5.2f}')            #Python 3.6
  print('%-10s %5.2f' % (b,eval(expr)))            #Python 2.7