Julia - JuMP constraints with array of tuples as indexes - indexing

The following is working in Julia JuMP:
#variable(m, δ[i=V, j=tildeV ; i != j && ŷ[i] < .5 && s[i,j] == sim_i[i]] >= 0)
While
Ω = [(i,j) for i in V, j in tildeV if i != j && ŷ[i] < .5 && s[i,j] == sim_i[i]]
#variable(m, δ[(i,j)=Ω] >= 0)
Results an error:
ERROR: UndefVarError: i not defined
What am I doing wrong? I could not find in the documentation. I tried: δ[(i,j)...=Ω] and δ[(i,j)=Ω...]
You might want to use a simpler Ω for minimal example like
Ω = [(i,j) for i in 1:5, j in 1:5]

These all work, so there must be a problem elsewhere in your code.
julia> S = [(1,2), (3,4)]
2-element Vector{Tuple{Int64, Int64}}:
(1, 2)
(3, 4)
julia> model = Model()
A JuMP Model
Feasibility problem with:
Variables: 0
Model mode: AUTOMATIC
CachingOptimizer state: NO_OPTIMIZER
Solver name: No optimizer attached.
julia> #variable(model, x[(i, j) = S])
1-dimensional DenseAxisArray{VariableRef,1,...} with index sets:
Dimension 1, [(1, 2), (3, 4)]
And data, a 2-element Vector{VariableRef}:
x[(1, 2)]
x[(3, 4)]
julia> Ω = [(i,j) for i in 1:5, j in 1:5]
5×5 Matrix{Tuple{Int64, Int64}}:
(1, 1) (1, 2) (1, 3) (1, 4) (1, 5)
(2, 1) (2, 2) (2, 3) (2, 4) (2, 5)
(3, 1) (3, 2) (3, 3) (3, 4) (3, 5)
(4, 1) (4, 2) (4, 3) (4, 4) (4, 5)
(5, 1) (5, 2) (5, 3) (5, 4) (5, 5)
julia> model = Model()
A JuMP Model
Feasibility problem with:
Variables: 0
Model mode: AUTOMATIC
CachingOptimizer state: NO_OPTIMIZER
Solver name: No optimizer attached.
julia> #variable(model, x[(i, j) = Ω])
1-dimensional DenseAxisArray{VariableRef,1,...} with index sets:
Dimension 1, [(1, 1) (1, 2) … (1, 4) (1, 5); (2, 1) (2, 2) … (2, 4) (2, 5); … ; (4, 1) (4, 2) … (4, 4) (4, 5); (5, 1) (5, 2) … (5, 4) (5, 5)]
And data, a 25-element Vector{VariableRef}:
x[(1, 1)]
x[(2, 1)]
x[(3, 1)]
x[(4, 1)]
x[(5, 1)]
x[(1, 2)]
x[(2, 2)]
x[(3, 2)]
x[(4, 2)]
x[(5, 2)]
⋮
x[(2, 4)]
x[(3, 4)]
x[(4, 4)]
x[(5, 4)]
x[(1, 5)]
x[(2, 5)]
x[(3, 5)]
x[(4, 5)]
x[(5, 5)]

Related

How does the reduce_agg function in presto work?

the docs explain reduce_agg here: https://prestodb.io/docs/current/functions/aggregate.html
reduce_agg(inputValue T, initialState S, inputFunction(S, T, S), combineFunction(S, S, S)) → S
Reduces all input values into a single value. inputFunction will be invoked for each input value. In addition to taking the input value, inputFunction takes the current state, initially initialState, and returns the new state. combineFunction will be invoked to combine two states into a new state. The final state is returned:
SELECT id, reduce_agg(value, 0, (a, b) -> a + b, (a, b) -> a + b)
FROM (
VALUES
(1, 2),
(1, 3),
(1, 4),
(2, 20),
(2, 30),
(2, 40)
) AS t(id, value)
GROUP BY id;
-- (1, 9)
-- (2, 90)
SELECT id, reduce_agg(value, 1, (a, b) -> a * b, (a, b) -> a * b)
FROM (
VALUES
(1, 2),
(1, 3),
(1, 4),
(2, 20),
(2, 30),
(2, 40)
) AS t(id, value)
GROUP BY id;
-- (1, 24)
-- (2, 24000)
What exactly does the combineFunction argument do?
Changing the combineFunction to the following all result in the same output.
SELECT id, reduce_agg(value, 0, (a, b) -> a + b, (a, b) -> 0)
FROM (
VALUES
(1, 2),
(1, 3),
(1, 4),
(2, 20),
(2, 30),
(2, 40)
) AS t(id, value)
GROUP BY id;
-- (1, 9)
-- (2, 90)
SELECT id, reduce_agg(value, 0, (a, b) -> a + b, (a, b) -> b)
FROM (
VALUES
(1, 2),
(1, 3),
(1, 4),
(2, 20),
(2, 30),
(2, 40)
) AS t(id, value)
GROUP BY id;
-- (1, 9)
-- (2, 90)

Create dataframe from rows which comprise differing column names

(Question rewritten as per comment-suggestions)
Suppose I have data like this:
{
2012: [ ('A', 9), ('C', 7), ('D', 4) ],
2013: [ ('B', 7), ('C', 6), ('E', 1) ]
}
How would I construct a dataframe that will account for the 'missing columns' in the rows?
i.e.
year A B C D E
0 2012 9 0 7 4 0
1 2013 0 7 6 0 1
I suppose I can perform a trivial preliminary manipulation to get:
[
[ ('year', 2012), ('A', 9), ('C', 7), ('D', 4) ],
[ ('year', 2013), ('B', 7), ('C', 6), ('E', 1) ]
]
You could first apply the method suggested in this post by #jezrael, create a df with the standard constructor, and then use df.pivot to get the df in the desired shape:
import pandas as pd
data = {
2012: [ ('A', 9), ('C', 7), ('D', 4) ],
2013: [ ('B', 7), ('C', 6), ('E', 1) ]
}
L = [(k, *t) for k, v in data.items() for t in v]
df = pd.DataFrame(L).rename(columns={0:'year'})\
.pivot(index='year', columns=1, values=2).fillna(0).reset_index(drop=False)
df.columns.name = None
print(df)
year A B C D E
0 2012 9.0 0.0 7.0 4.0 0.0
1 2013 0.0 7.0 6.0 0.0 1.0
If the values are all ints, you could do .fillna(0).astype(int).reset_index(drop=False), of course.
import pandas as pd
data = {
2012: [ ('A', 9), ('C', 7), ('D', 4) ],
2013: [ ('B', 7), ('C', 6), ('E', 1) ]
}
L = [(k, *t) for k, v in data.items() for t in v]
df = pd.DataFrame(L).rename(columns={0:'year'})\
.pivot(index='year', columns=1, values=2).fillna(0).reset_index(drop=False)
df.columns.name = None
df = df.astype({'A':'int','B':'int','C':'int','D':'int','E':'int'})

Sqlite Playing Cards Table

I'm learning SQL by using Sqlite. I want to create a simple deck of playing cards using Sqlite. My attempt is below.
Because I kept getting syntax errors I tried letting DB browser for Sqlite create the code to create the table by adding the fields manually. Now I'm left with some kind of hybrid syntax and I can't identify what the problems is when I put it through a syntax checker.
If I try and insert just one line:
INSERT INTO cards (name, suit, suit_symbol, score) VALUES (
-- Spades
("A", "spades", "♠", 1)
);
I get Uncaught Error: 1 values for 4 columns
If I try and run the whole thing, I get Uncaught Error: near ")": syntax error
I'm guessing there's at least two problems with my code, and part of the difficulty is that I have already learned a little MySQL which seems to be subtly and confusingly different.
Any help with getting my table built successfully in Sqlite and understanding why it doesn't work as is would be much appreciated.
--CREATE DATABASE IF NOT EXISTS cards;
CREATE TABLE IF not exists "cards" (
"id" INTEGER PRIMARY KEY AUTOINCREMENT,
"name" TEXT,
"suit" TEXT,
"suit_symbol" TEXT,
"score" INTEGER
);
INSERT INTO cards (name, suit, suit_symbol, score) VALUES (
-- Spades
("A", "spades", "♠", 1),
("2", "spades", "♠", 2),
("3", "spades", "♠", 3),
("4", "spades", "♠", 4),
("5", "spades", "♠", 5),
("6", "spades", "♠", 6),
("7", "spades", "♠", 7),
("8", "spades", "♠", 8),
("9", "spades", "♠", 9),
("10", "spades", "♠", 10),
("J", "spades", "♠", 11),
("Q", "spades", "♠", 12),
("K", "spades", "♠", 13),
-- Hearts
("A", "hearts", "♥", 1),
("2", "hearts", "♥", 2),
("3", "hearts", "♥", 3),
("4", "hearts", "♥", 4),
("5", "hearts", "♥", 5),
("6", "hearts", "♥", 6),
("7", "hearts", "♥", 7),
("8", "hearts", "♥", 8),
("9", "hearts", "♥", 9),
("10", "hearts", "♥", 10),
("J", "hearts", "♥", 11),
("Q", "hearts", "♥", 12),
("K", "hearts", "♥", 13),
-- Clubs
("A", "clubs", "♣", 1),
("2", "clubs", "♣", 2),
("3", "clubs", "♣", 3),
("4", "clubs", "♣", 4),
("5", "clubs", "♣", 5),
("6", "clubs", "♣", 6),
("7", "clubs", "♣", 7),
("8", "clubs", "♣", 8),
("9", "clubs", "♣", 9),
("10", "clubs", "♣", 10),
("J", "clubs", "♣", 11),
("Q", "clubs", "♣", 12),
("K", "clubs", "♣", 13),
-- Diamonds
("A", "diamonds", "♦", 1),
("2", "diamonds", "♦", 2),
("3", "diamonds", "♦", 3),
("4", "diamonds", "♦", 4),
("5", "diamonds", "♦", 5),
("6", "diamonds", "♦", 6),
("7", "diamonds", "♦", 7),
("8", "diamonds", "♦", 8),
("9", "diamonds", "♦", 9),
("10", "diamonds", "♦", 10),
("J", "diamonds", "♦", 11),
("Q", "diamonds", "♦", 12),
("K", "diamonds", "♦", 13),
);
There shouldn't be outer parenthesis around the tuples for values. Just a tuple is surrounded by parenthesis, multiple ones are separated by a comma.
Try:
INSERT INTO cards
(name,
suit,
suit_symbol,
score)
VALUES ('A', 'spades', '♠', 1),
('2', 'spades', '♠', 2),
...
('K', 'diamonds', '♦', 13);
And by the way: The proper quotes for string literals in SQL are single quotes. Double quotes are for identifiers. Though some DBMS accept to interchange them, it's a good idea to get used to the standard way, which is more likely to be cross platform.

pandas Multiindex - set_index with list of tuples

I experienced following issue. I have an existing MultiIndex and want to replace the single level with a list of tuples. But I got some strange value error
Code to reproduce:
idx = pd.MultiIndex.from_tuples([(1, u'one'), (1, u'two'),
(2, u'one'), (2, u'two')],
names=['foo', 'bar'])
idx.set_levels([3, 5], level=0) # works fine
idx.set_levels([(1,2),(3,4)], level=0) #TypeError: Levels must be list-like
Can anyone comment:
1) What's the issue?
2) What's the best method to replace index (int values -> tuple values)
Thanks!
For me working new contructor:
idx = pd.MultiIndex.from_product([[(1,2),(3,4)], idx.levels[1]], names=idx.names)
print (idx)
MultiIndex(levels=[[(1, 2), (3, 4)], ['one', 'two']],
labels=[[0, 0, 1, 1], [0, 1, 0, 1]],
names=['foo', 'bar'])
EIT1:
df = pd.DataFrame({'A':list('abcdef'),
'B':[1,2,1,2,2,1],
'C':[7,8,9,4,2,3],
'D':[1,3,5,7,1,0],
'E':[5,3,6,9,2,4],
'F':list('aaabbb')}).set_index(['B','C'])
#dynamic generate dictioanry with list of tuples
new = [(1, 2), (3, 4)]
d = dict(zip(df.index.levels[0], new))
print (d)
{1: (1, 2), 2: (3, 4)}
#explicit define dictionary
d = {1:(1,2), 2:(3,4)}
#rename first level of MultiInex
df = df.rename(index=d, level=0)
print (df)
A D E F
B C
(1, 2) 7 a 1 5 a
(3, 4) 8 b 3 3 a
(1, 2) 9 c 5 6 a
(3, 4) 4 d 7 9 b
2 e 1 2 b
(1, 2) 3 f 0 4 b
EDIT:
new = [(1, 2), (3, 4)]
lvl0 = list(map(tuple, np.array(new)[pd.factorize(idx.get_level_values(0))[0]].tolist()))
print (lvl0)
[(1, 2), (1, 2), (3, 4), (3, 4)]
idx = pd.MultiIndex.from_arrays([lvl0, idx.get_level_values(1)], names=idx.names)
print (idx)
MultiIndex(levels=[[(1, 2), (3, 4)], ['one', 'two']],
labels=[[0, 0, 1, 1], [0, 1, 0, 1]],
names=['foo', 'bar'])

Convert pandas Series/DataFrame to numpy matrix, unpacking coordinates from index

I have a pandas series as so:
A 1
B 2
C 3
AB 4
AC 5
BA 4
BC 8
CA 5
CB 8
Simple code to convert to a matrix as such:
1 4 5
4 2 8
5 8 3
Something fairly dynamic and built in, rather than many loops to fix this 3x3 problem.
You can do it this way.
import pandas as pd
# your raw data
raw_index = 'A B C AB AC BA BC CA CB'.split()
values = [1, 2, 3, 4, 5, 4, 8, 5, 8]
# reformat index
index = [(a[0], a[-1]) for a in raw_index]
multi_index = pd.MultiIndex.from_tuples(index)
df = pd.DataFrame(values, columns=['values'], index=multi_index)
df.unstack()
df.unstack()
Out[47]:
values
A B C
A 1 4 5
B 4 2 8
C 5 8 3
For pd.DataFrame uses .values member or else .to_records(...) method
For pd.Series use .unstack() method as Jianxun Li said
import numpy as np
import pandas as pd
d = pd.DataFrame(data = {
'var':['A','B','C','AB','AC','BA','BC','CA','CB'],
'val':[1,2,3,4,5,4,8,5,8] })
# Here are some options for converting to np.matrix ...
np.matrix( d.to_records(index=False) )
# matrix([[(1, 'A'), (2, 'B'), (3, 'C'), (4, 'AB'), (5, 'AC'), (4, 'BA'),
# (8, 'BC'), (5, 'CA'), (8, 'CB')]],
# dtype=[('val', '<i8'), ('var', 'O')])
# Here you can add code to rearrange it, e.g.
[(val, idx[0], idx[-1]) for val,idx in d.to_records(index=False) ]
# [(1, 'A', 'A'), (2, 'B', 'B'), (3, 'C', 'C'), (4, 'A', 'B'), (5, 'A', 'C'), (4, 'B', 'A'), (8, 'B', 'C'), (5, 'C', 'A'), (8, 'C', 'B')]
# and if you need numeric row- and col-indices:
[ (val, 'ABCDEF...'.index(idx[0]), 'ABCDEF...'.index(idx[-1]) ) for val,idx in d.to_records(index=False) ]
# [(1, 0, 0), (2, 1, 1), (3, 2, 2), (4, 0, 1), (5, 0, 2), (4, 1, 0), (8, 1, 2), (5, 2, 0), (8, 2, 1)]
# you can sort by them:
sorted([ (val, 'ABCDEF...'.index(idx[0]), 'ABCDEF...'.index(idx[-1]) ) for val,idx in d.to_records(index=False) ], key=lambda x: x[1:2] )